分享方式:


Azure Web PubSub 服務的本質

Azure Web PubSub 服務可讓您輕鬆地使用簡單 WebSocket 連線來發佈/訂閱訊息。

  • 您可以使用具有 Websocket 支援的任何語言來撰寫用戶端。
  • 一個連線內同時支援文字和二進位訊息。
  • 有簡單的通訊協定可供用戶端直接發佈用戶端對用戶端的訊息。
  • 此服務會為您管理 WebSocket 連線。

詞彙

  • 服務:Azure Web PubSub 服務。
  • 連線:連線也稱為用戶端或用戶端連線,代表連線到 Web PubSub 服務的個別 WebSocket 連線。 成功連線時,Web PubSub 服務會指派唯一的連線識別碼給這個連線。

  • 中樞:中樞是一組用戶端連線的邏輯概念。 您通常會針對一個案例使用一個中樞,例如,聊天中樞或通知中樞。 用戶端連線在連線時會連線到中樞,並且在其存留期內屬於該中樞。 用戶端連線一旦連線到中樞,中樞便會存在。 不同的應用程式可以使用不同的中樞名稱來共用一個 Azure Web PubSub 服務。 雖然中樞數目沒有嚴格限制,但與群組相比,中樞耗用更多服務負載。 建議有一組預先決定的中樞,而不是以動態方式產生中樞。

  • 群組:群組是中樞連線的子集。 您可以隨時將用戶端連線新增至某個群組,或從群組中移除用戶端連線。 例如,當用戶端加入聊天室時,或當用戶端離開聊天室時,便可將此聊天室視為群組。 用戶端可以加入多個群組,群組則可以包含多個用戶端。 群組就像是群組「會議」,一旦有人加入群組,系統就會建立群組會議,當群組中沒有任何人時,會議就會消失。 傳送至群組的訊息會傳遞至與群組連線的所有用戶端。

  • 使用者:Web PubSub 的連線可以屬於一個使用者。 使用者可能會有多個連線,例如,當單一使用者跨多個裝置或多個瀏覽器索引標籤連線時。

  • 訊息:當用戶端連線時,其可以透過 WebSocket 連線將訊息傳送至上游應用程式,或從上游應用程式接收訊息。 訊息可以是純文字、二進位或 JSON 格式,且大小上限為 1 MB。

  • 用戶端連線ConnectionId:用戶端會連線到 /client 端點,一旦連線,服務便會產生唯一的 connectionId,當作用戶端連線的唯一身分識別。 接著,使用者可以使用這個 connectionId 來管理用戶端連線。 <用戶端通訊協定>一節會有詳細說明。

  • 用戶端事件:系統會在用戶端連線的生命週期內建立事件。 例如,簡單 WebSocket 用戶端連線會在嘗試連線到服務時建立 connect 事件、在成功連線到服務時建立 connected 事件、在將訊息傳送到服務時建立 message 事件,以及在與服務中斷連線時建立 disconnected 事件。 <用戶端通訊協定>一節會有「用戶端事件」的詳細說明。

  • 事件處理常式:事件處理常式包含處理用戶端事件的邏輯。 請事先透過入口網站或 Azure CLI,在服務中註冊和設定事件處理常式。 <事件處理常式>一節會有詳細說明。

  • 事件接聽程式 (預覽):事件接聽程式只會接聽用戶端事件,但無法透過其回應干擾用戶端的存留期。 <事件接聽程式>一節會有詳細說明。

  • 伺服器:伺服器可以處理用戶端事件、管理用戶端連線,或將訊息發佈至群組。 事件處理常式和事件接聽程式都會視為伺服器端。 <伺服器通訊協定>一節會有伺服器的詳細說明。

工作流程

Diagram showing the Web PubSub service workflow.

如上圖所示的工作流程:

  1. 用戶端會使用 WebSocket 傳輸來連線到服務 /client 端點。 服務會將每個 WebSocket 框架轉送到設定的上游 (伺服器)。 WebSocket 連線可與任何自訂子通訊協定連線以供伺服器處理,也可與服務支援的子通訊協定 json.webpubsub.azure.v1 連線,讓用戶端能夠直接發佈/訂閱。 用戶端通訊協定中會有詳細說明。
  2. 在不同的用戶端事件上,服務會使用 CloudEvents 通訊協定叫用伺服器。 CloudEvents 會以標準化且與通訊協定無關的方式定義 Cloud Native Computing Foundation (CNCF) 所裝載事件的結構和中繼資料描述。 CloudEvents 通訊協定的詳細實作仰賴伺服器角色,如伺服器通訊協定所述。
  3. Web PubSub 伺服器可以使用 REST API 叫用服務,以將訊息傳送至用戶端或管理已連線的用戶端。 伺服器通訊協定會有詳細說明

用戶端通訊協定

用戶端連線會使用 WebSocket 通訊協定來連線至服務的 /client 端點。 WebSocket 通訊協定在 2011 年由 IETF 標準化為 RFC 6455,會透過單一 TCP 連線提供全雙工通訊通道。 大部分語言都有可啟動 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 用戶端遵循用戶端<->伺服器架構,如下列順序圖表所示:Diagram showing the sequence for a client connection.

  1. 當用戶端啟動 WebSocket 交握時,服務會嘗試叫用 connect 事件處理常式來處理 WebSocket 交握。 開發人員可以使用這個處理常式來處理 WebSocket 交握、判斷要使用的子通訊協定、驗證用戶端,以及將用戶端加入群組。
  2. 用戶端成功連線時,服務會叫用 connected 事件處理常式。 其會以通知的形式來運作,且不會阻止用戶端傳送訊息。 開發人員可以使用這個處理常式來儲存資料,而且可以透過訊息回應用戶端。 服務也會將 connected 事件推送至所有相關的事件接聽程式 (如果有的話)。
  3. 當用戶端傳送訊息時,服務會針對事件處理常式觸發 message 事件,以處理所傳送的訊息。 此事件是一般性事件,內含在 WebSocket 框架中所傳送的訊息。 您的程式碼必須在這個事件處理常式內分派訊息。 如果事件處理常式傳回非成功的回應碼,服務便會中斷用戶端連線。 服務也會將 message 事件推送至所有相關的事件接聽程式 (如果有的話)。 如果服務找不到任何已註冊的伺服器來接收訊息,服務也會中斷連線。
  4. 當用戶端中斷連線時,服務會在偵測到中斷連線的情況後,立即嘗試針對事件處理常式觸發 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 回應中指定用戶端擁有的 userIdrole 來驗證用戶端,或以 401 拒絕用戶端。 事件處理常式一節會有詳細說明。

下圖描述工作流程。

Diagram showing the client authentication workflow.

您可能已注意到,當我們描述 PubSub WebSocket 用戶端時,用戶端只有在獲得授權時才能發佈至其他用戶端。 用戶端的 role 決定用戶端所擁有初始權限:

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

伺服器端也可以透過伺服器通訊協定來動態授與或撤銷用戶端的權限,稍後一節會有說明。

伺服器通訊協定

伺服器通訊協定提供了相關功能,讓伺服器能夠處理用戶端事件和管理用戶端連線與群組。

一般來說,伺服器通訊協定包含三個角色:

  1. 事件處理常式
  2. [ODBC 目的地編輯器]
  3. 事件接聽程式

事件處理常式

事件處理常式會處理傳入的用戶端事件。 您可以透過入口網站或 Azure CLI,在服務中註冊和設定事件處理常式。 觸發用戶端事件時,服務可以識別是否要處理事件。 現在我們會使用 PUSH 模式來叫用事件處理常式。 伺服器端的事件處理常式會公開可公開存取的端點,讓服務能夠在觸發事件時叫用。 其會以 Webhook 的形式來運作。

Web PubSub 服務會使用 CloudEvents HTTP 通訊協定將用戶端事件傳遞至上游 Webhook。

針對每個事件,服務會向已註冊的上游制訂 HTTP POST 要求,且應該會有 HTTP 回應。

從服務傳送到伺服器的資料一律採用 CloudEvents binary 格式。

Diagram showing the Web PubSub service event push mode.

上游和驗證

您必須先透過入口網站或 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} 時,服務會嘗試將要求 OPTIONShttp://host.com/api/validate,而且只有在回應有效時,才能成功設定組態。

目前,我們不支援 WebHook-Request-RateWebHook-Request-Callback

服務與 Webhook 之間的驗證/授權

  • 匿名模式
  • 透過所設定的 Webhook URL 向 code 提供的簡單驗證。
  • 使用 Microsoft Entra 授權。 如需詳細資訊,請參閱如何使用受控識別以取得詳細資料。
    • 步驟 1:為 Web PubSub 服務啟用身分識別
    • 步驟 2:從代表您 Webhook Web 應用程式的現有 Microsoft Entra 應用程式中選取

[ODBC 來源編輯器]

伺服器本質上是授權使用者。 透過事件處理常式角色的協助,伺服器會知道用戶端的中繼資料 (例如 connectionIduserId),因此其能夠:

  • 關閉用戶端連線
  • 傳送訊息給用戶端
  • 傳送訊息給屬於相同使用者的用戶端
  • 將用戶端新增至群組
  • 將使用相同使用者身分進行驗證的用戶端新增至群組
  • 從群組中移除用戶端
  • 從群組中移除使用相同使用者身分進行驗證的用戶端
  • 向群組發佈訊息

其也可以向 PubSub 用戶端授與或撤銷發佈/加入權限:

  • 針對某些特定群組或針對所有群組授與發佈/加入權限
  • 針對某些特定群組或針對所有群組撤銷發佈/加入權限
  • 檢查用戶端是否有權加入或發佈至某些特定群組或所有群組

服務會提供 REST API 供伺服器管理連線。

Diagram showing the Web PubSub service connection manager workflow.

這裡定義了詳細的 REST API 通訊協定。

事件接聽程式

注意

事件接聽程式功能處於預覽狀態。

事件接聽程式會接聽傳入的用戶端事件。 每個事件接聽程式都有篩選條件能夠指定其關注的事件種類,以及指定要作為事件傳送目的地的端點。

我們目前支援以事件中樞作為事件接聽程式端點。

您必須事先註冊事件接聽程式,以便在觸發用戶端事件時,服務可以將事件推送至對應的事件接聽程式。 如需如何使用事件中樞端點來設定事件接聽程式的資訊,請參閱此文件

您可以設定多個事件接聽程式。 事件接聽程式的順序不重要。 如果事件符合多個事件接聽程式,則服務會將其傳送至其符合的所有接聽程式。 請參閱下列範例圖表。 假設您同時設定四個事件接聽程式。 然後,與其中三個接聽程式相符的用戶端事件會傳送至三個接聽程式,剩下的那個接聽程式保持不變。

Event listener data flow diagram sample

您可以合併相同事件的事件處理常式和事件接聽程式。 在此情況下,事件處理常式和事件接聽程式都會收到事件。

Web PubSub 服務會使用適用於 Azure Web PubSub 的 CloudEvents AMQP 擴充功能,將用戶端事件傳遞至事件接聽程式。

摘要

您可能已經注意到,事件處理常式角色會處理從服務到伺服器的通訊,管理員角色則會處理從伺服器到服務的通訊。 合併這兩個角色之後,服務與伺服器之間的資料流程看起來就像使用 HTTP 通訊協定的下圖。

Diagram showing the Web PubSub service bi-directional workflow.

下一步

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