分享方式:


適用於 Azure Web PubSub 的 WebSocket 用戶端通訊協定

用戶端使用標準 WebSocket 通訊協定來連線到 Azure Web PubSub。

服務端點

Web PubSub 服務提供兩種端點供用戶端連線:

  • /client/hubs/{hub}
  • /client/?hub={hub}

{hub} 是必要參數,用以隔離不同的應用程式。 可以在路徑或查詢中設定。

授權

用戶端使用 JSON Web 權杖 (JWT) 來連線到服務。 權杖可以位於查詢字串 (例如 /client/?hub={hub}&access_token={token}) 或 Authorization 標頭 (例如 Authorization: Bearer {token}) 中。

以下是一般授權工作流程:

  1. 用戶端與應用程式伺服器交涉。 應用程式伺服器包含授權中介軟體,可處理用戶端要求,並簽署 JWT 讓用戶端連線至服務。
  2. 應用程式伺服器將 JWT 和服務 URL 傳回給用戶端。
  3. 用戶端使用從應用程式伺服器傳回的 URL 和 JWT,嘗試連線到 Web PubSub 服務。

簡單的 WebSocket 用戶端

顧名思義,簡單的 WebSocket 用戶端就是簡單的 WebSocket 連線。 也可以有自己的自訂子通訊協定。

例如,在 JavaScript 中,您可以使用下列程式碼來建立簡單的 WebSocket 用戶端:

// simple WebSocket client1
var client1 = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1');

// simple WebSocket client2 with some custom subprotocol
var client2 = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'custom.subprotocol')

PubSub WebSocket 用戶端

PubSub WebSocket 用戶端使用 Azure Web PubSub 服務所定義的子通訊協定:

  • json.webpubsub.azure.v1
  • protobuf.webpubsub.azure.v1

透過服務支援的子通訊協定,PubSub WebSocket 用戶端只要具有權限,就可以直接將訊息發佈至群組。

json.webpubsub.azure.v1 子通訊協定

請參閱這裡以取得 JSON 子通訊協定的詳細資料

建立 PubSub WebSocket 用戶端

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

直接從用戶端加入群組

let ackId = 0;
pubsubClient.send(    
    JSON.stringify({
        type: 'joinGroup',
        group: 'group1',
        ackId: ++ackId
    }));

直接從用戶端將訊息傳送至群組

let ackId = 0;
pubsubClient.send(    
    JSON.stringify({
        type: 'sendToGroup',
        group: 'group1',
        ackId: ++ackId,
        dataType: "json",
        data: {
            "hello": "world"
        }
    }));

protobuf.webpubsub.azure.v1 子通訊協定

通訊協定緩衝區 (protobuf) 是一種語言中性、平台中性、二進位型的通訊協定,可簡化傳送二進位資料。 Protobuf 提供工具從許多語言產生用戶端,例如 JAVA、Python、Objective-C、C# 和 C++。 深入了解 protobuf

例如,在 JavaScript 中,您可以使用下列程式碼建立採用 protobuf 子通訊協定的 PubSub WebSocket 用戶端

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

請參閱這裡以取得 protobuf 子通訊協定的詳細資料

AckId 和認可回應

PubSub WebSocket 用戶端支援 joinGroupleaveGroupsendToGroupevent 訊息使用 ackId 屬性。 使用 ackId 時,您可以在處理要求後收到認可回應訊息。 在射後不理情節中,您可以選擇省略 ackId。 在本文中,我們說明指定或未指定 ackId 時的行為差異。

未指定 ackId 時的行為

如果未指定 ackId,則為射後不理。 即使代理訊息時發生錯誤,您也無法收到通知。

指定 ackId 時的行為

等冪發佈

ackId 是 uint64 數字,且應該在具有相同連線識別碼的用戶端內是唯一的。Web PubSub 服務會記錄 ackId,且具有相同 ackId 的訊息會視為相同訊息。 服務會拒絕多次代理相同的訊息,這在重試時很有用,可避免重複的訊息。 例如,如果用戶端傳送具有 ackId=5 的訊息,但無法接收具有 ackId=5 的認可回應,則用戶端會重試並再次傳送相同的訊息。 在某些情況下,已代理訊息,但認可回應因故遺失,此時服務會拒絕重試,並以 Duplicate 原因傳回認可回應。

認可回應

對於具有 ackId 的每個要求,Web PubSub 服務會傳送認可回應。

格式:

{
    "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>"
    }
}
  • ackId 與要求相關聯。

  • success 是 bool,指出服務是否成功處理要求。 如果是 false,則用戶端必須檢查 error

  • 只有當 successfalse 時,error 才存在,用戶端應該要有不同的邏輯來處理不同的 name。 您應該假設未來可能會有更多種 name

    • Forbidden:用戶端對要求沒有權限。 用戶端必須新增相關的角色。
    • InternalServerError:服務中發生內部錯誤。 需要重試。
    • Duplicate:服務已處理具有相同 ackId 的訊息。

權限

您在先前的 PubSub WebSocket 用戶端描述中可能注意到,用戶端只有在獲「授權」時,才能發佈至其他用戶端。 當用戶端正在連線或在連線的存留期內,可以授與用戶端的權限。

角色 權限
未指定 用戶端可以傳送事件要求。
webpubsub.joinLeaveGroup 用戶端可以加入或離開任何群組。
webpubsub.sendToGroup 用戶端可以將訊息發佈至任何群組。
webpubsub.joinLeaveGroup.<group> 用戶端可以加入或離開群組 <group>
webpubsub.sendToGroup.<group> 用戶端可以將訊息發佈至群組 <group>

有幾種方式可以授與用戶端的權限:

1.產生存取權杖時,將角色指派給用戶端

用戶端可以使用 JWT 權杖來連線到服務,權杖承載可以攜帶資訊,例如用戶端的 role。 簽署 JWT 權杖給用戶端時,您可以指定特定角色給用戶端,以授與用戶端的權限。

例如,讓我們簽署有權將訊息傳送至 group1group2 的 JWT 權杖:

let token = await serviceClient.getClientAccessToken({
    roles: [ "webpubsub.sendToGroup.group1", "webpubsub.sendToGroup.group2" ]
});

2.使用 connect 事件處理常式將角色指派給用戶端

註冊事件處理常式時 connect,也可以設定用戶端的角色,而上游事件處理常式在處理 roles 事件時,可以將用戶端的 connect 傳回至 Web PubSub 服務。

例如,在 JavaScript 中,您可以設定 handleConnect 事件來這麼做:

let handler = new WebPubSubEventHandler("hub1", {
  handleConnect: (req, res) => {
    // auth the connection and set the userId of the connection
    res.success({
      roles: [ "webpubsub.sendToGroup.group1", "webpubsub.sendToGroup.group2" ]
    });
  },
});

3.在執行階段透過 REST API 或伺服器 SDK 將角色指派給用戶端

let service = new WebPubSubServiceClient("<your_connection_string>", "test-hub");
await service.grantPermission("<connection_id>", "joinLeaveGroup", { targetName: "group1" });

下一步

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