使用 Azure SignalR 管理 SDK

Azure SignalR 管理 SDK 可以協助您透過 Azure SignalR Service 直接管理 SignalR 用戶端,例如廣播訊息。 因此,此 SDK 可以 (但不限於) 在無伺服器環境中使用。 您可以使用此 SDK 以在任何環境中管理連線至 Azure SignalR Service 的 SignalR 用戶端,例如主控台、 Azure 函數或網頁伺服器等環境。

注意

若要查看 SDK 1.9 版和之前版本的指南,請移至 Azure SignalR Service 管理 SDK (舊版)。 您可能也要閱讀移轉指引

功能

功能 暫時性 持續性
廣播 ✔️ ✔️
廣播 (除某些用戶端外) ✔️ ✔️
傳送至用戶端 ✔️ ✔️
傳送至用戶端 ✔️ ✔️
傳送給使用者 ✔️ ✔️
傳送給使用者 ✔️ ✔️
傳送至群組 ✔️ ✔️
傳送至群組 ✔️ ✔️
傳送至群組 (除某些用戶端外) ✔️ ✔️
將使用者新增至群組 ✔️ ✔️
從群組移除使用者 ✔️ ✔️
檢查使用者是否位於群組 ✔️ ✔️
多個 SignalR 服務執行個體支援 ✔️
MessagePack 用戶端支援 自 v1.21.0 起 自 v1.20.0 起
重試暫時性錯誤 自 v1.22.0 起

功能僅隨附於新的 API

功能 暫時性 持續性
檢查連線是否存在 ✔️ 自 v1.11 起
檢查群組是否存在 ✔️ 自 v1.11 起
檢查使用者是否存在 ✔️ 自 v1.11 起
關閉用戶端連線 ✔️ 自 v1.11 起
  • 如需關於不同模式的詳細資訊,請參閱這裡

  • 如需管理 SDK 的完整範例,請參閱這裡

使用方式

本節示範如何使用管理 SDK。

建立 Service Manager

ServiceManagerBuilder 建置 ServiceManager 的執行個體


var serviceManager = new ServiceManagerBuilder()
                    .WithOptions(option =>
                    {
                        option.ConnectionString = "<Your Azure SignalR Service Connection String>";
                    })
                    .WithLoggerFactory(loggerFactory)
                    .BuildServiceManager();

您可以使用 ServiceManager 以檢查 Azure SignalR 端點健康情況並建立服務中樞內容。 下一提供關於建立服務中書內容的詳細資料。

若要檢查 Azure SignalR 端點健康情況,則可以使用 ServiceManager.IsServiceHealthy 方法。 如果您使用多個 Azure SignalR 端點,僅檢查第一個端點。

var health = await serviceManager.IsServiceHealthy(cancellationToken);

建立服務中樞內容

ServiceManager 建立 ServiceHubContext 的執行個體:

var serviceHubContext = await serviceManager.CreateHubContextAsync("<Your Hub Name>",cancellationToken);

交涉

預設模式中,Azure SignalR Service SDK 進行交涉時會公開端點 /<Your Hub Name>/negotiate。 SignalR 用戶端會連線至此端點,然後稍後重新導向至 Azure SignalR Service。

無伺服器模式中,建議您裝載交涉端點以提供 SignalR 用戶端的交涉要求,並將用戶端重新導向至 Azure SignalR Service。

提示

如需關於重新導向的詳細資料,請參閱 SignalR 的交涉通訊協定

當您要將 SignalR 用戶端重新導向至 Azure SignalR Service 時,端點和存取權杖可以提供幫助。

您可以使用 ServiceHubContext 的執行個體以產生端點 URL 和對應存取權杖以讓 SignalR 用戶端連線至 Azure SignalR Service。

var negotiationResponse = await serviceHubContext.NegotiateAsync(new (){UserId = "<Your User Id>"});

假設您的中樞端點為 http://<Your Host Name>/<Your Hub Name>,交涉端點則為 http://<Your Host Name>/<Your Hub Name>/negotiate。 裝載交涉端點後,您可以使用 SignalR 用戶端以連線至中樞,如下列所示:

var connection = new HubConnectionBuilder().WithUrl("http://<Your Host Name>/<Your Hub Name>").Build();
await connection.StartAsync();

如需如何使用管理 SDK 將 SignalR 用戶端重新導向至 Azure SignalR Service 的範例,請參閱這裡

傳送訊息和管理群組

ServiceHubContextBuilder 建置的 ServiceHubContext 是實作和延伸 IServiceHubContext 的類別。 您可以使用其以將訊息傳送至用戶端和管理群組。

try
{
    // Broadcast
    await hubContext.Clients.All.SendAsync(callbackName, obj1, obj2, ...);

    // Send to user
    await hubContext.Clients.User(userId).SendAsync(callbackName, obj1, obj2, ...);

    // Send to group
    await hubContext.Clients.Group(groupId).SendAsync(callbackName, obj1, obj2, ...);

    // add user to group
    await hubContext.UserGroups.AddToGroupAsync(userId, groupName);

    // remove user from group
    await hubContext.UserGroups.RemoveFromGroupAsync(userId, groupName);
}
finally
{
    await hubContext.DisposeAsync();
}

強型別的中樞

強型別的中樞是程式設計模型,您可以將用戶端方法擷取至介面以避免錯誤,例如方法名稱拼寫錯誤或傳送錯誤參數類型。

假設我們有名為 ReceivedMessage 的用戶端方法,其中包含兩個字串參數。 如果沒有強型別的中樞,您會透過 hubContext.Clients.All.SendAsync("ReceivedMessage", user, message) 廣播至用戶端。 如果有強型別的中樞,您會先定義介面,如下所示:

public interface IChatClient
{
    Task ReceiveMessage(string user, string message);
}

然後,您會建立強型別的中樞內容以實作 IHubContext<Hub<T>, T>T 是用戶端方法介面:

ServiceHubContext<IChatClient> serviceHubContext = await serviceManager.CreateHubContextAsync<IChatClient>(hubName, cancellationToken);

最後,您可以直接叫用方法:

await Clients.All.ReceiveMessage(user, message);

除了傳送訊息的差異外,您可以使用 ServiceHubContext<T> (如同 ServiceHubContext) 交涉或管理群組。

如需 ASP.NET Core 文件的強型別中樞,請參閱這裡

傳輸類型

此 SDK 可以透過兩種傳輸類型與 Azure SignalR Service 通訊:

  • 暫時性:為每個傳送的訊息建立 HTTP 要求 Azure SignalR Service。 SDK 只會在暫時性模式中包裝 Azure SignalR Service REST API。 當您無法建立 WebSocket 連線時,這可以提供幫助。
  • 持續性:先建立 WebSocket 連線,然後傳送此連線中的所有訊息。 當您傳送大量訊息時,這可以提供幫助。

訊息中引數序序列化行為的摘要

序列化 暫時性 持續性
預設 JSON 程式庫 Newtonsoft.Json 與 ASP.NET Core SignalR 相同:
Newtonsoft.Json 適用於 .NET Standard 2.0;
System.Text.Json 適用於 .NET Core App 3.1 和更新版本
MessagePack 用戶端支援 自 v1.21.0 起 自 v1.20.0 起

JSON 序列化

在管理 SDK 中,傳送至用戶端的方法引數會序列化為 JSON。 自訂 JSON 序列化有數種方式。 我們會示範所有方式,順序為最建議到最不建議。

ServiceManagerOptions.UseJsonObjectSerializer(ObjectSerializer objectSerializer)

最建議的方式是使用一般抽象類別 ObjectSerializer,因為該類別支援不同的 JSON 序列化程式庫 (例如 System.Text.JsonNewtonsoft.Json) 並適用於所有傳輸類型。 您通常不需要自行實作 ObjectSerializer,因為已提供 System.Text.JsonNewtonsoft.Json 的 JSON 實作。

  • 使用 System.Text.Json 作為 JSON 處理程式庫時,內建的 JsonObjectSerializer 會使用 System.Text.Json.JsonSerializer 進行序列化/還原序列化。 以下是針對 JSON 序列化使用駝峰式大小寫命名的範例:

    var serviceManager = new ServiceManagerBuilder()
        .WithOptions(o =>
        {
            o.ConnectionString = "***";
            o.UseJsonObjectSerializer(new JsonObjectSerializer(new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            }));
        })
        .BuildServiceManager();
    
    
  • 使用 Newtonsoft.Json 作為 JSON 處理程式庫時,請先使用 .NET CLI 從 NuGet 安裝套件 Microsoft.Azure.Core.NewtonsoftJson

    dotnet add package Microsoft.Azure.Core.NewtonsoftJson
    

    以下是使用駝峰式大小寫命名與 NewtonsoftJsonObjectSerializer 的範例:

    var serviceManager = new ServiceManagerBuilder()
        .WithOptions(o =>
        {
            o.ConnectionString = "***";
            o.UseJsonObjectSerializer(new NewtonsoftJsonObjectSerializer(new JsonSerializerSettings()
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            }));
        })
        .BuildServiceManager();
    
  • 使用其他 JSON 處理程式庫時

    您也可以自行實作 ObjectSerializer。 下列連結可以提供幫助:

ServiceManagerBuilder.WithNewtonsoftJson(Action<NewtonsoftServiceHubProtocolOptions> configure)

此方法僅適用於 Newtonsoft.Json 使用者。 以下是使用駝峰式大小寫命名的範例:

var serviceManager = new ServiceManagerBuilder()
    .WithNewtonsoftJson(o =>
    {
        o.PayloadSerializerSettings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
    })
    .BuildServiceManager();
ServiceManagerOptions.JsonSerializerSettings (已淘汰)

此方法僅適用於暫時性傳輸類型。 不要使用此項。

var serviceManager = new ServiceManagerBuilder()
    .WithOptions(o =>
    {
        o.JsonSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    })
    .BuildServiceManager();

Message Pack 序列化

  1. 您必須安裝 Microsoft.AspNetCore.SignalR.Protocols.MessagePack 套件。

  2. 若要並列新增 MessagePack 通訊協定與預設 JSON 通訊協定:

    var serviceManagerBuilder = new ServiceManagerBuilder()
        .AddHubProtocol(new MessagePackHubProtocol());
    
  3. 若要完全控制中樞通訊協定,您可以使用

        var serviceManagerBuilder = new ServiceManagerBuilder()
            .WithHubProtocols(new MessagePackHubProtocol(), new JsonHubProtocol());
    

    WithHubProtocols 會先清除現有的通訊協定,然後新增通訊協定。 您也可以使用此方法以移除 JSON 通訊協定並僅使用 MessagePack。

針對暫時性模式,服務端預設會將 JSON 承載轉換為 MessagePack 承載,這是支援 MessagePack 的舊版方式。 不過,建議您明確新增 MessagePack 中樞通訊協定,因為舊版方式可能無法如預期運作。

HTTP 要求重試

針對暫時性模式,只要要求具有等冪性,此 SDK 能夠在發生暫時性錯誤時自動重新傳送要求。 若要啟用此功能,您可以使用 ServiceManagerOptions.RetryOptions 屬性。

特別會重試下列要求類型:

  • 針對將訊息傳送至 SignalR 用戶端的訊息要求,如果 HTTP 回應狀態代碼大於 500,則 SDK 會重試要求。 當 HTTP 回應代碼等於 500 時,這可能表示服務端逾時,而重試要求可能會導致訊息重複。

  • 針對其他要求類型 (例如將連線新增至群組),SDK 會在下列條件夏重試要求:

    1. HTTP 回應狀態代碼在 5xx 範圍內,或是狀態代碼為 408 (要求逾時) 的要求逾時。
    2. 要求逾時的持續時間大於 ServiceManagerOptions.HttpClientTimeout 中所設定的長度。

SDK 僅可以重試等冪要求,這些要求會在重複時沒有其他影響。 如果要求不具等冪性,則可能需要手動處理重試。

下一步

在本文中,您將了解如何在應用程式中使用 SignalR Service。 請參閱下列文章以了解有關 SignalR Service 的更多資訊。