適用於 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}
) 中。
以下是一般授權工作流程:
- 用戶端與應用程式伺服器交涉。 應用程式伺服器包含授權中介軟體,可處理用戶端要求,並簽署 JWT 讓用戶端連線至服務。
- 應用程式伺服器將 JWT 和服務 URL 傳回給用戶端。
- 用戶端會使用從應用程式伺服器傳回的 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 用戶端有兩種模式: sendEvent
和 sendToGroup
。 建立連接之後,即會決定模式,且稍後無法變更。
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=group1
中sendToGroup
建立簡單的 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
子通訊協定
建立 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');
AckId 和認可回應
PubSub WebSocket 用戶端支援 joinGroup
、leaveGroup
、sendToGroup
和 event
訊息使用 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
。只有當
success
為false
時,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 權杖給用戶端時,您可以指定特定角色給用戶端,以授與用戶端的權限。
例如,讓我們簽署有權將訊息傳送至 group1
和 group2
的 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" });
下一步
使用這些資源開始建置自己的應用程式: