Azure Web PubSub 支援的 protobuf WebSocket subprotocol
本文件描述子通訊協定 protobuf.webpubsub.azure.v1
。
當用戶端使用此子通訊協定時,傳出和傳入資料框架必須是通訊協定緩衝區 (protobuf) 承載。
概觀
子通訊協定 protobuf.webpubsub.azure.v1
可讓用戶端直接發佈/訂閱 (PubSub),而不是往返上游伺服器。 使用 protobuf.webpubsub.azure.v1
子通訊協定的 WebSocket 連線,稱為 PubSub WebSocket 用戶端。
例如,在 JavaScript 中,您可以使用下列方式來建立採用 protobuf 子通訊協定的 PubSub WebSocket 用戶端:
// PubSub WebSocket client
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'protobuf.webpubsub.azure.v1');
若為簡單的 WebSocket 用戶端,伺服器有處理用戶端事件的必要角色。 簡單的 WebSocket 連線一律會在傳送訊息時觸發 message
事件,而且一律依賴伺服器端來處理訊息並執行其他作業。 透過 protobuf.webpubsub.azure.v1
子通訊協定的協助,獲得授權的用戶端可以使用加入要求來加入群組,並使用發佈要求直接將訊息發佈至群組。 用戶端也可以使用事件要求來自訂訊息所屬的事件,將訊息路由至各種上游事件處理常式。
注意
目前,Web PubSub 服務僅支援 proto3。
權限
PubSub WebSocket 用戶端只能在授權時對其他用戶端發佈。 指派給用戶端的 roles
會決定授與給用戶端的權限:
角色 | 權限 |
---|---|
未指定 | 用戶端可以傳送事件要求。 |
webpubsub.joinLeaveGroup |
用戶端可以加入/離開任何群組。 |
webpubsub.sendToGroup |
用戶端可以將訊息發佈至任何群組。 |
webpubsub.joinLeaveGroup.<group> |
用戶端可以加入/離開群組 <group> 。 |
webpubsub.sendToGroup.<group> |
用戶端可以將訊息發佈至群組 <group> 。 |
伺服器可以透過 REST API 或伺服器 SDK 動態授與或撤銷用戶端權限。
要求
所有要求訊息都要遵守下列 protobuf 格式:
syntax = "proto3";
import "google/protobuf/any.proto";
message UpstreamMessage {
oneof message {
SendToGroupMessage send_to_group_message = 1;
EventMessage event_message = 5;
JoinGroupMessage join_group_message = 6;
LeaveGroupMessage leave_group_message = 7;
SequenceAckMessage sequence_ack_message = 8;
PingMessage ping_message = 9;
}
message SendToGroupMessage {
string group = 1;
optional uint64 ack_id = 2;
MessageData data = 3;
}
message EventMessage {
string event = 1;
MessageData data = 2;
optional uint64 ack_id = 3;
}
message JoinGroupMessage {
string group = 1;
optional uint64 ack_id = 2;
}
message LeaveGroupMessage {
string group = 1;
optional uint64 ack_id = 2;
}
message PingMessage {
}
}
message MessageData {
oneof data {
string text_data = 1;
bytes binary_data = 2;
google.protobuf.Any protobuf_data = 3;
}
}
加入群組
格式:
將 join_group_message.group
設定為群組名稱。
ackId
是每個要求的身分識別,且應該是唯一的。 服務會傳送認可回應訊息,以通知要求的處理結果。 如需詳細資訊,請參閱 AckId 和認可回應
離開群組
格式:
將 leave_group_message.group
設定為群組名稱。
ackId
是每個要求的身分識別,且應該是唯一的。 服務會傳送認可回應訊息,以通知要求的處理結果。 如需詳細資訊,請參閱 AckId 和認可回應
發佈訊息
格式:
ackId
:每個要求的唯一身分識別。 服務會傳送認可回應訊息,以通知要求的處理結果。 如需詳細資訊,請參閱 AckId 和認可回應dataType
:視MessageData
中的data
而定,資料格式可以是protobuf
、text
或binary
。 接收用戶端可以使用dataType
來正確處理內容。protobuf
:當您設定send_to_group_message.data.protobuf_data
時,隱含dataType
為protobuf
。protobuf_data
可以是任何訊息類型。 所有其他用戶端都會收到 protobuf 編碼的二進位檔,其可由 protobuf SDK 還原序列化。 僅支援文字型內容 (例如,json.webpubsub.azure.v1
) 的用戶端會接收 Base64 編碼的二進位檔。text
:當您設定send_to_group_message.data.text_data
時,隱含dataType
為text
。text_data
應該是字串。 具有其他通訊協定的所有用戶端都會接收 UTF-8 編碼的字串。binary
:當您設定send_to_group_message.data.binary_data
時,隱含dataType
為binary
。binary_data
應該是位元組陣列。 具有其他通訊協定的所有用戶端都會接收原始二進位檔,而不需要 protobuf 編碼。 僅支援文字型內容 (例如,json.webpubsub.azure.v1
) 的用戶端會接收 Base64 編碼的二進位檔。
案例 1:發佈文字資料
將 send_to_group_message.group
設定為 group
,並將 send_to_group_message.data.text_data
設定為 "text data"
。
群組
group
中的 protobuf 子通訊協定用戶端會接收二進位框架,而且可以使用 DownstreamMessage 將其還原序列化。group
中的 JSON 子通訊協定用戶端會接收:{ "type": "message", "from": "group", "group": "group", "dataType" : "text", "data" : "text data" }
group
中的簡單 WebSocket 用戶端會接收字串text data
。
案例 2:發佈 protobuf 資料
假設您有一則客戶訊息:
message MyMessage {
int32 value = 1;
}
使用 value = 1
將 send_to_group_message.group
設定為 group
以及將 send_to_group_message.data.protobuf_data
設定為 Any.pack(MyMessage)
。
group
中的 protobuf 子通訊協定用戶端會接收二進位框架,而且可以使用 DownstreamMessage 將其還原序列化。group
中的子通訊協定用戶端會接收:{ "type": "message", "from": "group", "group": "G", "dataType" : "protobuf", "data" : "Ci90eXBlLmdvb2dsZWFwaXMuY29tL2F6dXJlLndlYnB1YnN1Yi5UZXN0TWVzc2FnZRICCAE=" // Base64-encoded bytes }
注意
資料是 Base64 編碼的可還原序列化 protobuf 二進位檔。
您可以使用下列 protobuf 定義,並使用 Any.unpack()
來將其還原序列化:
syntax = "proto3";
message MyMessage {
int32 value = 1;
}
group
中的簡單 WebSocket 用戶端會接收二進位框架:# Show in hexadecimal 0A 2F 74 79 70 65 2E 67 6F 6F 67 6C 65 61 70 69 73 2E 63 6F 6D 2F 61 7A 75 72 65 2E 77 65 62 70 75 62 73 75 62 2E 54 65 73 74 4D 65 73 73 61 67 65 12 02 08 01
案例 3:發佈二進位資料
將 send_to_group_message.group
設定為 group
,並將 send_to_group_message.data.binary_data
設定為 [1, 2, 3]
。
群組
group
中的 protobuf 子通訊協定用戶端會接收二進位框架,而且可以使用 DownstreamMessage 將其還原序列化。群組
group
中的 JSON 子通訊協定用戶端會接收:{ "type": "message", "from": "group", "group": "group", "dataType" : "binary", "data" : "AQID", // Base64-encoded [1,2,3] }
因為 JSON 子通訊協定用戶端僅支援以文字為基礎的傳訊,所以二進位檔一律會以 Base64 編碼。
group
中的簡單 WebSocket 用戶端會接收二進位框架中的二進位資料:# Show in hexadecimal 01 02 03
傳送自訂事件
根據您設定的 dataType
,有一個隱含的 dataType
,可以是 protobuf
、text
或 binary
。 接收者用戶端可以使用 dataType
來正確處理內容。
protobuf
:當您設定event_message.data.protobuf_data
時,隱含dataType
為protobuf
。protobuf_data
值可為任何支援的 protobuf 類型。 事件處理常式會接收 protobuf 編碼的二進位檔,可由任何 protobuf SDK 進行還原序列化。text
:當您設定event_message.data.text_data
時,隱含dataType
為text
。text_data
值應該是字串。 事件處理常式會接收 UTF-8 編碼的字串。binary
:當您設定event_message.data.binary_data
時,隱含dataType
為binary
。binary_data
值應該是位元組陣列。 事件處理常式會接收原始二進位框架。
案例 1:使用文字資料傳送事件
將 event_message.data.text_data
設定為 "text data"
。
上游事件處理常式會接收類似以下的要求:
POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: text/plain
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.user.<event_name>
ce-source: /client/{connectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-userId: {userId}
ce-connectionId: {connectionId}
ce-hub: {hub_name}
ce-eventName: <event_name>
text data
CloudEvents HTTP 要求的 Content-Type
為 text/plain
,其中 dataType
=text
。
案例 2:使用 protobuf 資料傳送事件
假設您收到下列客戶訊息:
message MyMessage {
int32 value = 1;
}
將 event_message.data.protobuf_data
設定為具有 value = 1
的 any.pack(MyMessage)
上游事件處理常式會接收類似以下的要求:
POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: application/json
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.user.<event_name>
ce-source: /client/{connectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-userId: {userId}
ce-connectionId: {connectionId}
ce-hub: {hub_name}
ce-eventName: <event_name>
// Just show in hexadecimal; read it as binary
0A 2F 74 79 70 65 2E 67 6F 6F 67 6C 65 61 70 69 73 2E 63 6F 6D 2F 61 7A 75 72 65 2E 77 65 62 70 75 62 73 75 62 2E 54 65 73 74 4D 65 73 73 61 67 65 12 02 08 01
CloudEvents HTTP 要求的 Content-Type
為 application/x-protobuf
,其中 dataType
=protobuf
。
資料是有效的 protobuf 二進位檔。 您可以使用下列 proto
和 any.unpack()
將其還原序列化:
syntax = "proto3";
message MyMessage {
int32 value = 1;
}
案例 3:使用二進位資料傳送事件
將 send_to_group_message.binary_data
設定為 [1, 2, 3]
。
上游事件處理常式會接收類似以下的要求:
POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: application/octet-stream
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.user.<event_name>
ce-source: /client/{connectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-userId: {userId}
ce-connectionId: {connectionId}
ce-hub: {hub_name}
ce-eventName: <event_name>
// Just show in hexadecimal; you need to read it as binary
01 02 03
針對 dataType
=binary
,CloudEvents HTTP 要求的 Content-Type
為 application/octet-stream
。 若採用文字簡訊框架,則 WebSocket 框架可以採用 text
格式,或若為 binary
訊息框架,則為 UTF-8 編碼二進位。
如果訊息不符合描述的格式,服務就會拒絕用戶端。
Ping
用戶端可以將 傳送 PingMessage
至服務,讓 Web PubSub 服務偵測客戶端的活躍度。
回覆
所有回應訊息都要遵守下列 protobuf 格式:
message DownstreamMessage {
oneof message {
AckMessage ack_message = 1;
DataMessage data_message = 2;
SystemMessage system_message = 3;
PongMessage pong_message = 4;
}
message AckMessage {
uint64 ack_id = 1;
bool success = 2;
optional ErrorMessage error = 3;
message ErrorMessage {
string name = 1;
string message = 2;
}
}
message DataMessage {
string from = 1;
optional string group = 2;
MessageData data = 3;
}
message SystemMessage {
oneof message {
ConnectedMessage connected_message = 1;
DisconnectedMessage disconnected_message = 2;
}
message ConnectedMessage {
string connection_id = 1;
string user_id = 2;
}
message DisconnectedMessage {
string reason = 2;
}
}
message PongMessage {
}
}
用戶端收到的訊息可以是下列三種類型之一:ack
、 message
system
或 pong
。
認可回應
如果要求包含 ackId
,則服務會傳回此要求的認可回應。 用戶端實作應該處理此認可機制,包括:
- 等候作業的ack 回應
async
await
。 - 在特定期間內未收到認可回應時,進行逾時檢查。
用戶端實作應該一律先進行檢查,以查看 success
狀態為 true
還是 false
。 當 success
狀態為 false
時,用戶端可以從 error
屬性讀取,以取得錯誤詳細資料。
訊息回應
用戶端可以接收從用戶端已加入群組發佈的訊息。 或者,當伺服器傳送訊息給特定用戶端或特定使用者時,他們可以就從伺服器管理角色接收訊息。
您一律會在下列案例中收到 DownstreamMessage.DataMessage
訊息:
- 當訊息來自群組時,
from
為group
。 當訊息來自伺服器時,from
為server
。 - 當訊息來自群組時,
group
為群組名稱。
傳送者的 dataType
將會導致下列其中一則訊息傳送:
- 如果
dataType
為text
,請使用message_response_message.data.text_data
。 - 如果
dataType
為binary
,請使用message_response_message.data.binary_data
。 - 如果
dataType
為protobuf
,請使用message_response_message.data.protobuf_data
。 - 如果
dataType
為json
,請使用message_response_message.data.text_data
,而內容為序列化的 JSON 字串。
系統回應
Web PubSub 服務也可以將系統相關回應傳送給用戶端。
Connected
當用戶端連線到服務時,您會收到 DownstreamMessage.SystemMessage.ConnectedMessage
訊息。
已中斷連接
當伺服器關閉連線或當服務拒絕用戶端時,您會收到 DownstreamMessage.SystemMessage.DisconnectedMessage
訊息。
Pong 回應
Web PubSub 服務從用戶端接收 PingMessage
時,會將 傳送PongMessage
給用戶端。
下一步
使用這些資源開始建置自己的應用程式: