Azure SignalR Management SDK を使用する
Azure SignalR Management SDK は、ブロードキャスト メッセージなど、Azure SignalR Service を介して SignalR クライアントを直接管理するのに役立ちます。 そのため、この SDK はサーバーレス環境で使用できますが、これらに限定されるわけではありません。 この SDK を使用して、コンソール アプリ、Azure 関数、Web サーバーなどの任意の環境で Azure SignalR Service に接続されている SignalR クライアントを管理できます。
Note
SDK バージョン 1.9.x 以前のガイドについては、「Azure SignalR Service Management SDK (レガシ)」を参照してください。 移行のガイダンスもお読みください。
機能
機能 | 一時的 | 永続的 |
---|---|---|
Broadcast | ✔️ | ✔️ |
一部のクライアントを除くブロードキャスト | ✔️ | ✔️ |
1 クライアントに送信 | ✔️ | ✔️ |
複数クライアントに送信 | ✔️ | ✔️ |
ユーザーに送信する | ✔️ | ✔️ |
複数ユーザーに送信 | ✔️ | ✔️ |
グループに送信する | ✔️ | ✔️ |
複数グループに送信 | ✔️ | ✔️ |
一部のクライアントを除いてグループに送信 | ✔️ | ✔️ |
1 ユーザーを 1 グループに追加 | ✔️ | ✔️ |
1 グループから 1 ユーザーを削除 | ✔️ | ✔️ |
グループ内のユーザーかを確認 | ✔️ | ✔️ |
複数の SignalR サービス インスタンスのサポート | ❌ | ✔️ |
MessagePack クライアントのサポート | v1.21.0 以降 | v1.20.0 以降 |
一時的なエラーの再試行 | v1.22.0 以降 | ❌ |
新しい API にのみ付属する機能
機能 | 一時的 | 永続的 |
---|---|---|
接続が存在するかどうかを確認 | ✔️ | v1.11 以降 |
グループが存在するかどうかを確認 | ✔️ | v1.11 以降 |
ユーザーが存在するかどうかを確認 | ✔️ | v1.11 以降 |
クライアント接続を閉じる | ✔️ | v1.11 以降 |
さまざまなモードの詳細については、こちらをご覧ください。
管理 SDK の全てのサンプルについては、こちらをご覧ください。
使用方法
このセクションでは、Management SDK の使用方法を示します。
サービス マネージャーの作成
ServiceManagerBuilder
から ServiceManager
のインスタンスを構築します
var serviceManager = new ServiceManagerBuilder()
.WithOptions(option =>
{
option.ConnectionString = "<Your Azure SignalR Service Connection String>";
})
.WithLoggerFactory(loggerFactory)
.BuildServiceManager();
Azure SignalR エンドポイントの正常性を確認し、サービス ハブ コンテキストを作成するために ServiceManager
を使用できます。 次のセクションでは、サービス ハブ コンテキストの作成について詳しく説明します。
Azure SignalR エンドポイントの正常性を確認するには、ServiceManager.IsServiceHealthy
メソッドを使用できます。 複数の Azure SignalR エンドポイントがある場合は、最初のエンドポイントのみがチェックされます。
var health = await serviceManager.IsServiceHealthy(cancellationToken);
サービス ハブ コンテキストの作成
ServiceManager
から ServiceHubContext
のインスタンスを作成します。
var serviceHubContext = await serviceManager.CreateHubContextAsync("<Your Hub Name>",cancellationToken);
ネゴシエーション
この既定モードでは、エンドポイント /<Your Hub Name>/negotiate
が Azure SignalR Service SDK によるネゴシエーションのために公開されます。 SignalR クライアントはこのエンドポイントに到達し、後で Azure SignalR Service にリダイレクトします。
サーバーレス モードでは、SignalR クライアントのネゴシエート要求に対応し、クライアントを Azure SignalR Service にリダイレクトするために、ネゴシエーション エンドポイントをホストすることをお勧めします。
ヒント
リダイレクトの詳細については、SignalR のネゴシエーション プロトコルを参照してください。
エンドポイントとアクセス トークンは共に、SignalR クライアントを Azure SignalR Service にリダイレクトする場合に便利です。
ServiceHubContext
のインスタンスを使用して、SignalR クライアントが Azure SignalR Service に接続するためのエンドポイント URL と対応するアクセス トークンを生成できます。
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();
}
厳密に型付けされたハブ
厳密に型付けされたハブは、メソッド名のスペルミスや間違ったパラメーター型の渡しなどのエラーを回避できるように、クライアント メソッドをインターフェイスに抽出できるプログラミング モデルです。
たとえば、2 つの文字列パラメーターを持つ 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
と同じように ServiceHubContext<T>
を使用してグループをネゴシエートまたは管理することができます。
厳密に型付けされたハブの詳細については、こちらの ASP.NET Core ドキュメントを参照してください。
トランスポートの種類
この SDK は、次の 2 種類のトランスポートを使用して Azure SignalR Service と通信できます。
- 一時的: 送信された各メッセージに対して Http 要求 Azure SignalR Service を作成します。 SDK は、単に Azure SignalR Service REST API を一時的モードでラップします。 WebSocket 接続を確立できない場合に便利です。
- 永続的: 最初に WebSocket 接続を作成してから、この接続内のすべてのメッセージを送信します。 大量のメッセージを送信する場合に便利です。
メッセージ内の引数のシリアル化動作の概要
シリアル化 | 一時的 | 永続的 |
---|---|---|
既定の JSON ライブラリ | Newtonsoft.Json |
ASP.NET Core SignalR と同じ。 .NET Standard 2.0 の場合 Newtonsoft.Json 。.NET Core App 3.1 以降の場合 System.Text.Json 。 |
MessagePack クライアントのサポート | v1.21.0 以降 | v1.20.0 以降 |
JSON シリアル化
Management SDK では、クライアントに送信されるメソッド引数は JSON にシリアル化されます。 JSON シリアル化をカスタマイズするには、いくつかの方法があります。 最も推奨されるものから最も推奨されないものまで順にすべての方法を示します。
ServiceManagerOptions.UseJsonObjectSerializer(ObjectSerializer objectSerializer)
最も推奨される方法は、一般的な抽象クラス ObjectSerializer
を使用することです。これは、System.Text.Json
や Newtonsoft.Json
などのさまざまな JSON シリアル化ライブラリをサポートし、すべてのトランスポートの種類に適用されるためです。 通常は、System.Text.Json
や Newtonsoft.Json
のための便利な JSON 実装が既に提供されているため、ObjectSerializer
を自分で実装する必要はありません。
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
(非推奨)
ServiceManagerOptions.JsonSerializerSettings
このメソッドは、一時的モードのトランスポートにのみ適用されます。 これは使用しません。
var serviceManager = new ServiceManagerBuilder()
.WithOptions(o =>
{
o.JsonSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
})
.BuildServiceManager();
メッセージ パックのシリアル化
Microsoft.AspNetCore.SignalR.Protocols.MessagePack
パッケージをインストールする必要があります。既定の JSON プロトコルと並行して MessagePack プロトコルを追加するには、次を使用します。
var serviceManagerBuilder = new ServiceManagerBuilder() .AddHubProtocol(new MessagePackHubProtocol());
ハブ プロトコルを完全に制御するには、次を使用します。
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 は次の条件下で要求を再試行します。
- HTTP 応答の状態コードが 5xx の範囲内であるか、要求が 408 (要求タイムアウト) の状態コードでタイムアウトした。
- 要求が、
ServiceManagerOptions.HttpClientTimeout
で構成されているタイムアウト時間よりも長い時間でタイムアウトした。
SDK はべき等要求のみを再試行できます。これは、繰り返された場合に他の効果を持たない要求です。 要求がべき等でない場合は、手動で再試行を処理することが必要な場合があります。
次のステップ
この記事では、アプリケーションで SignalR Service を使用する方法について説明しました。 SignalR Service のさらなる詳細については、次の記事を参照してください。