Azure Web PubSub 可靠 JSON WebSocket 子通訊協定

JSON WebSocket 子通訊協定 json.reliable.webpubsub.azure.v1,可讓您透過服務直接在用戶端之間進行發佈/訂閱訊息的高度可靠交換,而不需要往返於上游伺服器。

本文件描述子通訊協定 json.reliable.webpubsub.azure.v1。

當 WebSocket 用戶端連線因為間歇性網路問題而中斷時,訊息可能會遺失。 在發佈/訂閱系統中,發行者會與訂閱者分離,因此發行者很難偵測訂閱者的連線中斷或訊息遺失。

若要克服間歇性網路問題並維護可靠的訊息傳遞,您可以使用 Azure WebPubSub json.reliable.webpubsub.azure.v1 子通訊協定來建立可靠的 PubSub WebSocket 用戶端。

可靠的 PubSub WebSocket 用戶端可以:

例如,您可以使用下列 JavaScript 程式碼建立可靠的 PubSub WebSocket 用戶端:

var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'json.reliable.webpubsub.azure.v1');

請參閱如何建立可靠的用戶端,為發行者和訂閱者用戶端實作重新連線和訊息可靠性。

當用戶端使用這個子通訊協定時,傳出和傳入資料框架都必須包含 JSON 承載。

權限

PubSub WebSocket 用戶端只能在授權時對其他用戶端發佈。 指派給用戶端的 roles 會決定授與給用戶端的權限:

角色 權限
未指定 用戶端可以傳送事件要求。
webpubsub.joinLeaveGroup 用戶端可以加入/離開任何群組。
webpubsub.sendToGroup 用戶端可以將訊息發佈至任何群組。
webpubsub.joinLeaveGroup.<group> 用戶端可以加入/離開群組 <group>。
webpubsub.sendToGroup.<group> 用戶端可以將訊息發佈至群組 <group>。
webpubsub.joinLeaveGroups.<pattern> 客戶端可以加入或離開任何名稱相符 <pattern> 的群組(參見 萬用卡群組角色模式)。
webpubsub.sendToGroups.<pattern> 用戶端可以向任何名稱相符 <pattern> 的群組發布訊息(參見 萬用字群組角色模式)。

伺服器可以透過 REST API 或伺服器 SDK 動態授與或撤銷用戶端權限。

備註

REST API 或伺服器 SDK 在執行時尚未支援萬用卡角色(例如 webpubsub.sendToGroups.<pattern>)。

要求

加入群組

格式:

{
    "type": "joinGroup",
    "group": "<group_name>",
    "ackId" : 1
}

離開群組

格式:

{
    "type": "leaveGroup",
    "group": "<group_name>",
    "ackId" : 1
}

發佈訊息

格式:

{
    "type": "sendToGroup",
    "group": "<group_name>",
    "ackId" : 1,
    "noEcho": true|false,
    "dataType" : "json|text|binary",
    "data": {}, // data can be string or valid json token depending on the dataType 
}
  • ackId 是每個要求的身分識別,且應該是唯一的。 服務會傳送認可回應訊息,以通知要求的處理結果。 如需詳細資訊,請參閱 AckId 和 Ack 回應
  • noEcho 是選擇性的。 如果設定為 true,則此訊息不會回應到相同的連線。 如果未設定,預設值為 false。
  • dataType 可以設定為 json、text 或 binary:
    • json:data 可以是 JSON 支援的任何類型,且將按原樣發佈;如果未指定 dataType,則預設為 json。
    • text:data 應採用字串格式,且將發佈字串資料;
    • binary:data 應採用 base64 格式,且將發佈二進位資料;

案例 1:發佈文字資料:

{
    "type": "sendToGroup",
    "group": "<group_name>",
    "dataType" : "text",
    "data": "text data",
    "ackId": 1
}
  • <group_name> 中的子通訊協定用戶端會接收:
{
    "type": "message",
    "from": "group",
    "group": "<group_name>",
    "dataType" : "text",
    "data" : "text data"
}
  • <group_name> 中的簡單 WebSocket 用戶端會接收字串 text data。

案例 2:發佈 JSON 資料:

{
    "type": "sendToGroup",
    "group": "<group_name>",
    "dataType" : "json",
    "data": {
        "hello": "world"
    }
}
  • <group_name> 中的子通訊協定用戶端會接收:
{
    "type": "message",
    "from": "group",
    "group": "<group_name>",
    "dataType" : "json",
    "data" : {
        "hello": "world"
    }
}
  • <group_name> 中的簡單 WebSocket 用戶端會接收序列化字串 {"hello": "world"}。

案例 3:發佈二進位資料:

{
    "type": "sendToGroup",
    "group": "<group_name>",
    "dataType" : "binary",
    "data": "<base64_binary>",
    "ackId": 1
}
  • <group_name> 中的子通訊協定用戶端會接收:
{
    "type": "message",
    "from": "group",
    "group": "<group_name>",
    "dataType" : "binary",
    "data" : "<base64_binary>", 
}
  • <group_name> 中的簡單 WebSocket 用戶端會接收二進位框架中的二進位資料。

開始串流訊息

要啟動群組串流,請發送 sendToGroup 帶有屬性的 stream 請求。 串流開始請求不包含 data、 dataType或 ackId。

格式:

{
    "type": "sendToGroup",
    "group": "<group_name>",
    "noEcho": true|false,
    "stream": {
        "streamId": "<stream_id>",
        "idleTimeoutMs": 300000
    }
}
  • stream.streamId 是邏輯串流的識別碼。 它必須是非空的字串,且在同一客戶端連線上的多個活躍串流中必須是唯一的。 建議用戶端函式庫產生全球唯一值,例如 GUID 或 UUID。
  • stream.idleTimeoutMs 是選擇性的。 若指定,則必須大於 0。 若省略,服務預設為 300000 毫秒。 這個值是閒置逾時,而非整個串流壽命。 傳送串流資料、傳送串流保持連線,或在此逾時前結束串流,當應用程式需要保持串流開啟時。
  • noEcho 是選擇性的。 如果設定為 true,串流訊息不會被回傳到同一個連線。 如果未設定,預設值為 false。

當串流被接受時,用戶端會收到一個設定expectedSequenceId為 1的串流 ack 回應。

傳送串流資料

要傳送串流資料,請發送streamData一個請求,包含 streamId、 streamSequenceId、 dataTypedata和 。

格式:

{
    "type": "streamData",
    "streamId": "<stream_id>",
    "streamSequenceId": 1,
    "dataType" : "json|text|binary",
    "data": {}
}
  • streamId 識別同一用戶端連線上的活躍串流。
  • streamSequenceId 是正的uint64數值。 串流中的第一個資料片段使用 1,而後續每個相同 streamId 資料片段則會增加恰好 1。
  • dataType 可以設定為 json、 text或 binary,使用與 發佈訊息相同的資料編碼規則。

若要保持串流活躍而不傳送資料給訂閱者,請發送streamData僅typestreamId與 的請求。

{
    "type": "streamData",
    "streamId": "<stream_id>"
}

結束串流訊息

要結束直播,請發送 streamEnd 請求。

格式:

{
    "type": "streamEnd",
    "streamId": "<stream_id>"
}

若要以應用程式定義錯誤結束串流,請加入可選 error 屬性。

{
    "type": "streamEnd",
    "streamId": "<stream_id>",
    "error": {
        "message": "<error_detail>",
        "userErrorCode": "<application_error_code>"
    }
}
  • error.message 是一個可選的人類可讀錯誤訊息。
  • error.userErrorCode 是可選的應用程式定義錯誤碼。

當串流被關閉時,出版者會收到串流 關閉回應。

傳送自訂事件

格式:

{
    "type": "event",
    "event": "<event_name>",
    "ackId": 1,
    "dataType" : "json|text|binary",
    "data": {}, // data can be string or valid json token depending on the dataType 
}

dataType 可以是 text、binary 或 json:

  • json:資料可以是 JSON 支援的任何類型,且將按原樣發佈;預設值為 json。
  • text:資料為字串格式,且將發佈字串資料;
  • binary:資料為 base64 格式,且將發佈二進位資料;

案例 1:使用文字資料傳送事件:

{
    "type": "event",
    "event": "<event_name>",
    "ackId": 1,
    "dataType" : "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

當 Content-Type 是 text/plain 時,CloudEvents HTTP 要求的 dataType 為 text。

案例 2:使用 JSON 資料傳送事件:

{
    "type": "event",
    "event": "<event_name>",
    "ackId": 1,
    "dataType" : "json",
    "data": {
        "hello": "world"
    }, 
}

上游事件處理常式會接收類似以下的資料:

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>

{
    "hello": "world"
}

當 Content-Type 是 application/json 時,CloudEvents HTTP 要求的 dataType 為 json

案例 3:使用二進位資料傳送事件:

{
    "type": "event",
    "event": "<event_name>",
    "ackId": 1,
    "dataType" : "binary",
    "data": "base64_binary", 
}

上游事件處理常式會接收類似以下的資料:

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>

binary

當 Content-Type 是 application/octet-stream 時,CloudEvents HTTP 要求的 dataType 為 binary。 若採用文字簡訊框架,則 WebSocket 框架可以是 text 格式,或若為 binary 訊息框架,則為 UTF8 編碼二進位。

如果訊息不符合描述的格式,Web PubSub 服務就會拒絕用戶端。

Ping

格式:

{
    "type": "ping",
}

用戶端可以將訊息傳送 ping 至服務,讓 Web PubSub 服務偵測客戶端的活躍度。

序列認可

格式:

{
    "type": "sequenceAck",
    "sequenceId": "<sequenceId>",
}

可靠的 PubSub WebSocket 用戶端在收到來自服務的訊息後,必須隨即傳送序列認可訊息。 如需詳細資訊,請參閱如何建立可靠的用戶端

  • sequenceId 是收到的訊息中累加的 uint64 數值。

回覆

客戶端收到的訊息可以有多種類型:ack、pongsystemstreamAckmessagestreamNack和。streamClosed 類型 message 的訊息具有 sequenceId 屬性。 用戶端在收到訊息後,必須隨即傳送序列認可給服務。

認可回應

當要求包含 ackId 時,則服務會傳回此要求的認可回應。 用戶端實作應該處理此 ack 機制,包括使用asyncawait作業等候 ack 回應,並在特定期間未收到 ack 回應時擁有逾時處理程式。

格式:

{
    "type": "ack",
    "ackId": 1, // The ack id for the request to ack
    "success": false, // true or false
    "error": {
        "name": "Forbidden|InternalServerError|Duplicate",
        "message": "<error_detail>"
    }
}

用戶端實作應一律先檢查 success 是否為 true 或 false。 只有當 success 是 false 時,用戶端才會讀取 error。

訊息回應

用戶端可以接收從用戶端已加入的群組或從伺服器發佈的訊息,以伺服器管理角色操作,將訊息傳送至特定用戶端或使用者。

  1. 來自群組的回應訊息:

    {
        "sequenceId": 1,
        "type": "message",
        "from": "group",
        "group": "<group_name>",
        "dataType": "json|text|binary",
        "data" : {} // The data format is based on the dataType
        "fromUserId": "abc"
    }
    
  2. 來自伺服器的回應訊息:

    {
        "sequenceId": 1,
        "type": "message",
        "from": "server",
        "dataType": "json|text|binary",
        "data" : {} // The data format is based on the dataType
    }
    

案例 1:透過 REST API 並使用 Hello WorldContent-Type=,將資料 text/plain 傳送至連線

  • 簡單的 WebSocket 用戶端接收的內容是包含資料的文字 WebSocket 框架:Hello World;

  • PubSub WebSocket 用戶端會接收 JSON 格式的訊息:

    {
        "sequenceId": 1,
        "type": "message",
        "from": "server",
        "dataType" : "text",
        "data": "Hello World", 
    }
    

案例 2:透過 REST API 並使用 { "Hello" : "World"}Content-Type=,將資料 application/json 傳送至連線

  • 簡單的 WebSocket 用戶端接收的內容是包含字串化資料的文字 WebSocket 框架:{ "Hello" : "World"};

  • PubSub WebSocket 用戶端會接收 JSON 格式的訊息:

    {
        "sequenceId": 1,
        "type": "message",
        "from": "server",
        "dataType" : "json",
        "data": {
            "Hello": "World"
        }
    }
    

如果 REST API 使用 Hello World 內容類型傳送字串 application/json,簡單的 WebSocket 用戶端會接收包裝在 "Hello World" 中的 JSON 字串 "。

案例 3:透過 REST API 並使用 Content-Type=application/octet-stream,將二進位資料傳送至連線

  • 簡單的 WebSocket 用戶端所接收的內容是含有二進位資料的二進位 WebSocket 框架。

  • PubSub WebSocket 用戶端會接收 JSON 格式的訊息:

    {
        "sequenceId": 1,
        "type": "message",
        "from": "server",
        "dataType" : "binary",
        "data": "<base64_binary>"
    }
    

串流訊息回應

當訊息屬於串流時,群組訊息包含一個 stream 屬性。 可靠 sequenceId 值仍維持連接範圍,且與 stream.streamSequenceId不同。

{
    "sequenceId": 1,
    "type": "message",
    "from": "group",
    "group": "<group_name>",
    "dataType": "json|text|binary",
    "data": {},
    "fromUserId": "abc",
    "stream": {
        "streamId": "<stream_id>",
        "streamSequenceId": 1,
        "endOfStream": true,
        "error": {
            "name": "IdleTimeout|InternalServerError|Forbidden|Cancelled|UserError",
            "message": "<error_detail>",
            "userErrorCode": "<application_error_code>"
        }
    }
}
  • stream.streamId 是邏輯串流識別碼。
  • stream.streamSequenceId 是串流中訊息的序號。
  • stream.endOfStream 是選擇性的。 當 設為 true時,訊息即為串流的終端訊息。
  • stream.error 是可選的,僅在串流以錯誤結束時才會出現。 userErrorCode 僅存在於 UserError。

串流 ack 回應

服務會 streamAck 發送回應以確認已接受的串流資料,並回報它預期的下一個串流序列 ID。

格式:

{
    "type": "streamAck",
    "streamId": "<stream_id>",
    "expectedSequenceId": 2
}

Stream nack 回應

服務會 streamNack 針對可重試串流錯誤發送回應。

格式:

{
    "type": "streamNack",
    "streamId": "<stream_id>",
    "expectedSequenceId": 2,
    "name": "InvalidSequenceId|TransientError",
    "message": "<error_detail>"
}

串流閉合反應

當發佈者端的串流關閉時,服務會 streamClosed 發送回應。

格式:

{
    "type": "streamClosed",
    "streamId": "<stream_id>",
    "error": {
        "name": "StreamNotFound|Forbidden|BadRequest|InternalServerError|IdleTimeout",
        "message": "<error_detail>"
    }
}

當溪流正常閉合時,此 error 性質被省略。

系統回應

Web PubSub 服務也可以將系統相關回應傳回給用戶端。

Pong 回應

Web PubSub 服務從用戶端接收pong訊息時,會將訊息傳送ping給用戶端。

格式:

{
    "type": "pong",
}

Connected

對用戶端連線要求的回應:

{
    "type": "system",
    "event": "connected",
    "userId": "user1",
    "connectionId": "abcdefghijklmnop",
    "reconnectionToken": "<token>"
}

connectionId 和 reconnectionToken 會用於重新連線。 請使用 URI 提出連線要求以進行重新連線:

wss://<service-endpoint>/client/hubs/<hub>?awps_connection_id=<connectionId>&awps_reconnection_token=<reconnectionToken>

在連線復原中可找到詳細資料

已中斷連接

伺服器關閉連線時或服務拒絕用戶端連線時的回應:

{
    "type": "system",
    "event": "disconnected",
    "message": "reason"
}

下一步

使用這些資源開始建置自己的應用程式: