Azure Web PubSub 服務的本質
Azure Web PubSub 服務可讓您輕鬆地使用簡單 WebSocket 連線來發佈/訂閱訊息。
- 您可以使用具有 Websocket 支援的任何語言來撰寫用戶端。
- 一個連線內同時支援文字和二進位訊息。
- 簡單的通訊協定可讓客戶直接發佈按摩。
- 此服務會為您管理 WebSocket 連線。
詞彙
- 服務:Azure Web PubSub 服務。
連線:連線,也稱為用戶端或用戶端連線,這是用戶端與 Web PubSub 服務之間的邏輯關聯性。 透過「連線」,用戶端和服務會參與一系列具狀態互動。 使用不同通訊協定的連線可能會有不同運作方式,例如,某些連線僅限於網路連線的持續時間,而其他連線則可跨用戶端與服務之間的多個連續網路連線進行擴充。
中樞:中樞是一組用戶端連線的邏輯概念。 您通常會針對一個案例使用一個中樞,例如,聊天中樞或通知中樞。 用戶端連線在連線時會連線到中樞,並且在其存留期內屬於該中樞。 用戶端連線一旦連線到中樞,中樞便會存在。 不同的應用程式可以使用不同的中樞名稱來共用一個 Azure Web PubSub 服務。 雖然中樞數目沒有嚴格限制,但與群組相比,中樞耗用更多服務負載。 建議有一組預先決定的中樞,而不是以動態方式產生中樞。
群組:群組是中樞連線的子集。 您可以隨時將用戶端連線新增至某個群組,或從群組中移除用戶端連線。 例如,當用戶端加入聊天室時,或當用戶端離開聊天室時,便可將此聊天室視為群組。 用戶端可以加入多個群組,群組則可以包含多個用戶端。 群組就像是群組「會議」,一旦有人加入群組,系統就會建立群組會議,當群組中沒有任何人時,會議就會消失。 傳送至群組的訊息會傳遞至與群組連線的所有用戶端。
使用者:Web PubSub 的連線可以屬於一個使用者。 使用者可能會有多個連線,例如,當單一使用者跨多個裝置或多個瀏覽器索引標籤連線時。
訊息:當用戶端連線時,其可以透過 WebSocket 連線將訊息傳送至上游應用程式,或從上游應用程式接收訊息。 訊息可以是純文字、二進位或 JSON 格式,且大小上限為 1 MB。
用戶端事件:系統會在用戶端連線的生命週期內建立事件。 例如,簡單 WebSocket 用戶端連線會在嘗試連線到服務時建立
connect
事件、在成功連線到服務時建立connected
事件、在將訊息傳送到服務時建立message
事件,以及在與服務中斷連線時建立disconnected
事件。 <用戶端通訊協定>一節會有「用戶端事件」的詳細說明。事件處理常式:事件處理常式包含處理用戶端事件的邏輯。 請事先透過入口網站或 Azure CLI,在服務中註冊和設定事件處理常式。 <事件處理常式>一節會有詳細說明。
事件接聽程式 (預覽):事件接聽程式只會接聽用戶端事件,但無法透過其回應干擾用戶端的存留期。 <事件接聽程式>一節會有詳細說明。
伺服器:伺服器可以處理用戶端事件、管理用戶端連線,或將訊息發佈至群組。 事件處理常式和事件接聽程式都會視為伺服器端。 <伺服器通訊協定>一節會有伺服器的詳細說明。
工作流程
如上圖所示的工作流程:
- 用戶端會使用 WebSocket 傳輸來連線到服務
/client
端點。 服務會將每個 WebSocket 框架轉送到設定的上游 (伺服器)。 WebSocket 連線可與任何自訂子通訊協定連線以供伺服器處理,也可與服務支援的子通訊協定json.webpubsub.azure.v1
連線,讓用戶端能夠直接發佈/訂閱。 用戶端通訊協定中會有詳細說明。 - 在不同的用戶端事件上,服務會使用 CloudEvents 通訊協定叫用伺服器。 CloudEvents 會以標準化且與通訊協定無關的方式定義 Cloud Native Computing Foundation (CNCF) 所裝載事件的結構和中繼資料描述。 CloudEvents 通訊協定的詳細實作仰賴伺服器角色,如伺服器通訊協定所述。
- Web PubSub 伺服器可以使用 REST API 叫用服務,以將訊息傳送至用戶端或管理已連線的用戶端。 伺服器通訊協定會有詳細說明
用戶端通訊協定
用戶端連線會使用 WebSocket 通訊協定來連線至服務的 /client
端點。 WebSocket 通訊協定在 2011 年由 IETF 標準化為 RFC 6455,會透過單一 TCP 連線提供全雙工通訊通道。 大部分語言都有可啟動 WebSocket 連線的原生支援。
我們的服務支援兩種用戶端:
- 一種稱為簡單 WebSocket 用戶端
- 另一種稱為 PubSub WebSocket 用戶端
簡單 WebSocket 用戶端
正如其名,簡單 WebSocket 用戶端是簡單 WebSocket 連線。 其也可以有自訂的子通訊協定。
例如在 JS 中,您可以使用下列程式碼來建立簡單 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 用戶端會遵循客戶端<->伺服器架構,如下圖所示:
- 當用戶端啟動 WebSocket 交握時,服務會嘗試叫用
connect
事件處理常式來處理 WebSocket 交握。 開發人員可以使用這個處理常式來處理 WebSocket 交握、判斷要使用的子通訊協定、驗證用戶端,以及將用戶端加入群組。 - 用戶端成功連線時,服務會叫用
connected
事件處理常式。 其會以通知的形式來運作,且不會阻止用戶端傳送訊息。 開發人員可以使用這個處理常式來儲存資料,而且可以透過訊息回應用戶端。 服務也會將connected
事件推送至所有相關的事件接聽程式 (如果有的話)。 - 當用戶端傳送訊息時,服務會將
message
事件觸發至事件處理程式。 此事件包含 WebSocket 框架中傳送的訊息。 您的程式碼必須在這個事件處理常式內分派訊息。 如果事件處理程式傳回非成功回應碼,服務就會卸除用戶端連線。 如果有任何事件,服務也會將message
事件推送至所有相關的事件接聽程式。 如果服務找不到任何已註冊的伺服器來接收訊息,服務也會卸載用戶端連線。 - 當用戶端中斷連線時,服務會在偵測到中斷連線的情況後,立即嘗試針對事件處理常式觸發
disconnected
事件。 服務也會將disconnected
事件推送至所有相關的事件接聽程式 (如果有的話)。
案例
這些連線可用於典型的用戶端-伺服器架構,在此架構中,用戶端會將訊息傳送至伺服器,而伺服器會使用事件處理常式處理傳入的訊息。 當客戶在其應用程式邏輯中套用現有的子通訊協定時,也可以使用事件處理常式。
PubSub WebSocket 用戶端
服務也支援稱為 json.webpubsub.azure.v1
的特定子通訊協定,可讓用戶端直接發佈/訂閱,而不必往返上游伺服器。 我們將使用 json.webpubsub.azure.v1
子通訊協定的 WebSocket 連線稱為 PubSub WebSocket 用戶端。 如需詳細資訊,請參閱 GitHub 上的 Web PubSub 用戶端規格。
例如在 JS 中,您可以使用下列程式碼來建立 PubSub WebSocket 用戶端。
// PubSub WebSocket client
var pubsub = new WebSocket(
"wss://test.webpubsub.azure.com/client/hubs/hub1",
"json.webpubsub.azure.v1"
);
PubSub WebSocket 用戶端可以:
加入群組,例如:
{ "type": "joinGroup", "group": "<group_name>" }
退出群組,例如:
{ "type": "leaveGroup", "group": "<group_name>" }
向群組發佈訊息,例如:
{ "type": "sendToGroup", "group": "<group_name>", "data": { "hello": "world" } }
將自訂事件傳送至上游伺服器,例如:
{ "type": "event", "event": "<event_name>", "data": { "hello": "world" } }
PubSub WebSocket 子通訊協定包含 json.webpubsub.azure.v1
子通訊協定的詳細資料。
您注意到,對於簡單的 WebSocket 用戶端,伺服器必須是 角色,才能從用戶端接收message
事件。 簡單的 WebSocket 連線一律會在傳送訊息時觸發 message
事件,而且一律依賴伺服器端來處理訊息並執行其他作業。 透過 json.webpubsub.azure.v1
子通訊協定的協助,獲得授權的用戶端可以加入群組,並直接向群組發佈訊息。 其也可以自訂訊息所屬的事件,以將訊息路由傳送至不同的事件處理常式/事件接聽程式。
案例
當用戶端想要彼此通訊時,便可使用這類用戶端。 如果用戶端已獲得操作授權,訊息便會從 client2
傳送至服務,而服務會將訊息直接傳遞至 client1
。
Client1:
var client1 = new WebSocket(
"wss://xxx.webpubsub.azure.com/client/hubs/hub1",
"json.webpubsub.azure.v1"
);
client1.onmessage = (e) => {
if (e.data) {
var message = JSON.parse(e.data);
if (message.type === "message" && message.group === "Group1") {
// Only print messages from Group1
console.log(message.data);
}
}
};
client1.onopen = (e) => {
client1.send(
JSON.stringify({
type: "joinGroup",
group: "Group1",
})
);
};
Client2:
var client2 = new WebSocket("wss://xxx.webpubsub.azure.com/client/hubs/hub1", "json.webpubsub.azure.v1");
client2.onopen = e => {
client2.send(JSON.stringify({
type: "sendToGroup",
group: "Group1",
data: "Hello Client1"
});
};
如上述範例所示,client2
會藉由將訊息發佈至 client1
所在的 Group1
中,將資料直接傳送至 client1
。
用戶端事件摘要
用戶端事件分為兩種類別:
同步事件 (封鎖) 同步事件會封鎖用戶端工作流程。
connect
:此事件僅適用於事件處理常式。 用戶端在啟動 WebSocket 交握時會觸發事件,開發人員可以使用connect
事件處理常式來處理 WebSocket 交握、判斷要使用的子通訊協定、驗證用戶端,以及將用戶端加入群組。message
:用戶端在傳送訊息時會觸發此事件。
異步事件 (非封鎖) 異步事件不會封鎖用戶端工作流程。 相反地,他們會將通知傳送至伺服器。 當這類事件觸發程序失敗時,服務便會記錄錯誤詳細資料。
connected
:用戶端在成功連線到服務時會觸發此事件。disconnected
:用戶端在與服務中斷連線時會觸發此事件。
用戶端訊息限制
一個 WebSocket 框架允許的訊息大小上限為 1 MB。
用戶端驗證
驗證工作流程
用戶端會使用已簽署的 JWT 權杖來連線到服務。 上游也可以在有傳入用戶端的 connect
事件處理常式時拒絕用戶端。 事件處理常式會藉由在 Webhook 回應中指定用戶端擁有的 userId
和 role
來驗證用戶端,或以 401 拒絕用戶端。 事件處理常式一節會有詳細說明。
下圖描述工作流程。
用戶端只有在獲授權時,才能發佈至其他用戶端。 用戶端 role
的 會決定 客戶端擁有的初始 權限:
角色 | 權限 |
---|---|
未指定 | 用戶端可以傳送事件。 |
webpubsub.joinLeaveGroup |
用戶端可以加入/離開任何群組。 |
webpubsub.sendToGroup |
用戶端可以將訊息發佈至任何群組。 |
webpubsub.joinLeaveGroup.<group> |
用戶端可以加入/離開群組 <group> 。 |
webpubsub.sendToGroup.<group> |
用戶端可以將訊息發佈至群組 <group> 。 |
伺服器端也可以透過伺服器通訊協定來動態授與或撤銷用戶端的權限,稍後一節會有說明。
伺服器通訊協定
伺服器通訊協定提供了相關功能,讓伺服器能夠處理用戶端事件和管理用戶端連線與群組。
一般來說,伺服器通訊協定包含三個角色:
事件處理常式
事件處理常式會處理傳入的用戶端事件。 您可以透過入口網站或 Azure CLI,在服務中註冊和設定事件處理常式。 觸發用戶端事件時,服務可以識別是否要處理事件。 現在我們會使用 PUSH
模式來叫用事件處理常式。 伺服器端的事件處理常式會公開可公開存取的端點,讓服務能夠在觸發事件時叫用。 其會以 Webhook 的形式來運作。
Web PubSub 服務會使用 CloudEvents HTTP 通訊協定將用戶端事件傳遞至上游 Webhook。
針對每個事件,服務會向已註冊的上游制訂 HTTP POST 要求,且應該會有 HTTP 回應。
從服務傳送到伺服器的資料一律採用 CloudEvents binary
格式。
上游和驗證
您必須先透過入口網站或 Azure CLI,在服務中註冊和設定事件處理常式,才能進行首次的使用。 觸發用戶端事件時,服務可以識別是否必須處理事件。 在公開預覽時,我們會使用 PUSH
模式來叫用事件處理常式。 伺服器端的事件處理常式會公開可公開存取的端點,讓服務能夠在觸發事件時叫用。 其會作為 Webhook 上游。
URL 可以使用 {event}
參數來定義 Webhook 處理常式的 URL 範本。 當用戶端要求傳入時,服務會動態計算 Webhook URL 的值。 例如,當 /client/hubs/chat
要求傳入,且已為中樞 chat
設定了事件處理常式 URL 模式 http://host.com/api/{event}
時,這時如果用戶端連線,其會先 POST (張貼) 到此 URL:http://host.com/api/connect
。 當 PubSub WebSocket 用戶端傳送自訂事件時,事件處理常式會協助將不同的事件分派至不同的上游,這時此行為會很有用。 URL 網域名稱中不允許 {event}
參數。
透過 Azure 入口網站或 CLI 設定事件處理常式上游時,服務會遵循 CloudEvents 濫用保護來驗證上游 Webhook。 WebHook-Request-Origin
要求標頭會設定為服務網域名稱 xxx.webpubsub.azure.com
,而且其預期回應會有 WebHook-Allowed-Origin
標頭以包含此網域名稱。
在進行驗證時,{event}
參數會解析為 validate
。 例如,在嘗試將 URL 設定為 http://host.com/api/{event}
時,服務會嘗試將要求 OPTIONS 到 http://host.com/api/validate
,而且只有在回應有效時,才能成功設定組態。
目前,我們不支援 WebHook-Request-Rate 和 WebHook-Request-Callback。
服務與 Webhook 之間的驗證/授權
若要在服務與 Webhook 之間建立安全驗證和授權,請考慮下列選項和步驟:
- 匿名模式
- 透過所設定的 Webhook URL 向
code
提供的簡單驗證。 - 使用 Microsoft Entra 授權。 如需詳細資訊,請參閱如何使用受控識別以取得詳細資料。
- 啟用 Web PubSub 服務的身分識別。
- 從代表 Webhook Web 應用程式的現有Microsoft Entra 應用程式選取。
[ODBC 來源編輯器]
伺服器本質上是授權使用者。 透過事件處理常式角色的協助,伺服器會知道用戶端的中繼資料 (例如 connectionId
和 userId
),因此其能夠:
- 關閉用戶端連線
- 傳送訊息給用戶端
- 傳送訊息給屬於相同使用者的用戶端
- 將用戶端新增至群組
- 將使用相同使用者身分進行驗證的用戶端新增至群組
- 從群組中移除用戶端
- 從群組中移除使用相同使用者身分進行驗證的用戶端
- 向群組發佈訊息
其也可以向 PubSub 用戶端授與或撤銷發佈/加入權限:
- 針對某些特定群組或針對所有群組授與發佈/加入權限
- 針對某些特定群組或針對所有群組撤銷發佈/加入權限
- 檢查用戶端是否有權加入或發佈至某些特定群組或所有群組
服務會提供 REST API 供伺服器管理連線。
這裡定義了詳細的 REST API 通訊協定。
事件接聽程式
注意
事件接聽程式功能處於預覽狀態。
事件接聽程式會接聽傳入的用戶端事件。 每個事件接聽程式都有篩選條件能夠指定其關注的事件種類,以及指定要作為事件傳送目的地的端點。
我們目前支援以事件中樞作為事件接聽程式端點。
您必須事先註冊事件接聽程式,以便在觸發用戶端事件時,服務可以將事件推送至對應的事件接聽程式。 如需如何使用事件中樞端點來設定事件接聽程式的資訊,請參閱此文件。
您可以設定多個事件接聽程式。 您設定它們的順序不會影響其功能。 如果事件符合多個接聽程式,則會將事件分派至所有相符的接聽程式。 請參閱下列範例圖表。 例如,如果您同時設定四個事件接聽程式,則每個接收相符專案的接聽程式都會處理事件。 與其中三個接聽程式相符的用戶端事件會傳送至三個接聽程式,並忽略其餘接聽程式。
您可以合併相同事件的事件處理常式和事件接聽程式。 在此情況下,事件處理程式和事件接聽程式都會接收 事件。
Web PubSub 服務會使用適用於 Azure Web PubSub 的 CloudEvents AMQP 擴充功能,將用戶端事件傳遞至事件接聽程式。
摘要
事件處理程式角色會處理從服務到伺服器的通訊,而管理員角色則會處理從伺服器到服務的通訊。 結合這兩個角色之後,服務與伺服器之間的數據流看起來會類似下圖使用 HTTP 通訊協定。
下一步
使用這些資源開始建置自己的應用程式: