共用方式為


適用於 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 服務。

支援的宣告

您也可以藉由在 JWT 令牌內指定特殊宣告,在產生存取權杖時設定客戶端連線的屬性:

描述 宣告類型 宣告值 備註
userId用戶端連線的 sub userId 只允許一個 sub 宣告。
令牌的存留期 exp 到期時間 exp (到期時間) 宣告會識別令牌必須接受處理之到期時間或之後的到期時間。
用戶端連接一開始擁有的許可權 role 許可權中 定義的角色值 如果用戶端具有多個許可權,請指定多個 role 宣告。
用戶端連線一旦連線到 Azure Web PubSub,用戶端連線就會加入的初始群組 webpubsub.group 要加入的群組 如果客戶端聯結多個群組,請指定多個 webpubsub.group 宣告。

您也可以將自定義宣告新增至存取令牌,而且這些值會保留為claims連接上游要求本文中的 屬性。

伺服器 SDK 提供 API 來產生用戶端的存取令牌。

簡單的 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')

簡單的 WebSocket 用戶端有兩種模式: sendEventsendToGroup。 建立連接之後,即會決定模式,且稍後無法變更。

sendEvent 是簡單 WebSocket 用戶端的預設模式。 在模式中 sendEvent ,用戶端傳送的每個 WebSocket 框架都會被視為 message 事件。 用戶可以設定 事件處理程式事件接聽程式 來處理這些 message 事件。

// Every data frame is considered as a `message` event
var client3 = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1');

// Or explicitly set the mode
var client4 = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1?webpubsub_mode=sendEvent');

在模式中 sendToGroup ,用戶端傳送的每個 WebSocket 框架都會被視為要發行至特定群組的訊息。 group 是此模式中的必要查詢參數,而且只允許單一值。 線上也應該具有將訊息傳送至目標群組的對應 許可權webpubsub.sendToGroup.<group>webpubsub.sendToGroup 角色都適用於它。

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

var client5 = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1?webpubsub_mode=sendToGroup&group=group1');

PubSub WebSocket 用戶端

PubSub WebSocket 用戶端是 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 的認可回應,則用戶端會重試並再次傳送相同的訊息。 在某些情況下,訊息已經代理,且因某些原因而遺失 ack 回應。 服務會拒絕重試,並回應有原因的 Duplicate ack 回應。

認可回應

對於具有 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" });

下一步

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