のハブを SignalR ASP.NET Core に使用するUse hubs in SignalR for ASP.NET Core
Rachel appelおよび加山 GriffinBy Rachel Appel and Kevin Griffin
サンプル コードを表示またはダウンロードする (ダウンロード方法)View or download sample code (how to download)
ハブとは SignalRWhat is a SignalR hub
SignalRハブ API を使用すると、接続されているクライアント上のメソッドをサーバーから呼び出すことができます。The SignalR Hubs API enables you to call methods on connected clients from the server. サーバーコードでは、クライアントによって呼び出されるメソッドを定義します。In the server code, you define methods that are called by client. クライアントコードでは、サーバーから呼び出されるメソッドを定義します。In the client code, you define methods that are called from the server. SignalR は、クライアントとサーバー間のリアルタイム通信とサーバー間の通信を可能にする、バックグラウンドの背後にあるすべての処理を行います。SignalR takes care of everything behind the scenes that makes real-time client-to-server and server-to-client communications possible.
ハブの構成 SignalRConfigure SignalR hubs
ミドルウェアには SignalR 、を呼び出すことによって構成されるいくつかのサービスが必要です services.AddSignalR
。The SignalR middleware requires some services, which are configured by calling services.AddSignalR
.
services.AddSignalR();
SignalRASP.NET Core アプリに機能を追加する場合、 SignalR endpoint.MapHub
Startup.Configure
メソッドのコールバックでを呼び出すことによってルートをセットアップし app.UseEndpoints
ます。When adding SignalR functionality to an ASP.NET Core app, setup SignalR routes by calling endpoint.MapHub
in the Startup.Configure
method's app.UseEndpoints
callback.
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<ChatHub>("/chathub");
});
ASP.NET Core アプリに機能を追加するときに SignalR 、 SignalR メソッドでを呼び出すことによってルートをセットアップし app.UseSignalR
Startup.Configure
ます。When adding SignalR functionality to an ASP.NET Core app, setup SignalR routes by calling app.UseSignalR
in the Startup.Configure
method.
app.UseSignalR(route =>
{
route.MapHub<ChatHub>("/chathub");
});
ハブの作成と使用Create and use hubs
から継承するクラスを宣言してハブを作成 Hub
し、パブリックメソッドを追加します。Create a hub by declaring a class that inherits from Hub
, and add public methods to it. クライアントは、として定義されているメソッドを呼び出すことができ public
ます。Clients can call methods that are defined as public
.
public class ChatHub : Hub
{
public Task SendMessage(string user, string message)
{
return Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
C# のメソッドの場合と同様に、戻り値の型とパラメーター (複合型や配列を含む) を指定できます。You can specify a return type and parameters, including complex types and arrays, as you would in any C# method. SignalR パラメーターと戻り値の複合オブジェクトおよび配列のシリアル化と逆シリアル化を処理します。SignalR handles the serialization and deserialization of complex objects and arrays in your parameters and return values.
注意
ハブは一時的なものです。Hubs are transient:
- ハブクラスのプロパティに状態を格納しないでください。Don't store state in a property on the hub class. すべてのハブメソッド呼び出しは、新しいハブインスタンスで実行されます。Every hub method call is executed on a new hub instance.
await
ハブをキープアライブに依存する非同期メソッドを呼び出すときに使用します。Useawait
when calling asynchronous methods that depend on the hub staying alive. たとえば、をClients.All.SendAsync(...)
指定せずに呼び出され、await
ハブメソッドが終了する前に完了した場合、などのメソッドは失敗する可能性がSendAsync
あります。For example, a method such asClients.All.SendAsync(...)
can fail if it's called withoutawait
and the hub method completes beforeSendAsync
finishes.
コンテキストオブジェクトThe Context object
Hub
クラスには、 Context
接続に関する情報を含む次のプロパティを含むプロパティがあります。The Hub
class has a Context
property that contains the following properties with information about the connection:
プロパティProperty | [説明]Description |
---|---|
ConnectionId |
によって割り当てられる、接続の一意の ID を取得し SignalR ます。Gets the unique ID for the connection, assigned by SignalR. 接続ごとに1つの接続 ID があります。There is one connection ID for each connection. |
UserIdentifier |
ユーザー識別子を取得します。Gets the user identifier. 既定では、は、 SignalR ClaimTypes.NameIdentifier ClaimsPrincipal 接続に関連付けられているのをユーザー識別子として使用します。By default, SignalR uses the ClaimTypes.NameIdentifier from the ClaimsPrincipal associated with the connection as the user identifier. |
User |
現在の ClaimsPrincipal ユーザーに関連付けられているを取得します。Gets the ClaimsPrincipal associated with the current user. |
Items |
この接続のスコープ内でデータを共有するために使用できるキー/値のコレクションを取得します。Gets a key/value collection that can be used to share data within the scope of this connection. このコレクションにデータを格納することができ、さまざまなハブメソッド呼び出し間の接続が維持されます。Data can be stored in this collection and it will persist for the connection across different hub method invocations. |
Features |
接続で使用できる機能のコレクションを取得します。Gets the collection of features available on the connection. 現時点では、ほとんどのシナリオでこのコレクションは必要ないため、詳細には記載されていません。For now, this collection isn't needed in most scenarios, so it isn't documented in detail yet. |
ConnectionAborted |
CancellationToken 接続が中止されたときに通知するを取得します。Gets a CancellationToken that notifies when the connection is aborted. |
Hub.Context
には、次のメソッドも含まれています。Hub.Context
also contains the following methods:
メソッドMethod | 説明Description |
---|---|
GetHttpContext |
HttpContext 接続のを返し null ます。接続が HTTP 要求に関連付けられていない場合はを返します。Returns the HttpContext for the connection, or null if the connection is not associated with an HTTP request. HTTP 接続の場合は、このメソッドを使用して、HTTP ヘッダーやクエリ文字列などの情報を取得できます。For HTTP connections, you can use this method to get information such as HTTP headers and query strings. |
Abort |
接続を中止します。Aborts the connection. |
クライアントオブジェクトThe Clients object
Hub
クラスには、 Clients
サーバーとクライアント間の通信に関する次のプロパティを含むプロパティがあります。The Hub
class has a Clients
property that contains the following properties for communication between server and client:
プロパティProperty | [説明]Description |
---|---|
All |
接続されているすべてのクライアントでメソッドを呼び出しますCalls a method on all connected clients |
Caller |
ハブメソッドを呼び出したクライアントでメソッドを呼び出します。Calls a method on the client that invoked the hub method |
Others |
メソッドを呼び出したクライアントを除く、接続されているすべてのクライアントでメソッドを呼び出します。Calls a method on all connected clients except the client that invoked the method |
Hub.Clients
には、次のメソッドも含まれています。Hub.Clients
also contains the following methods:
メソッドMethod | 説明Description |
---|---|
AllExcept |
指定された接続を除く、接続されているすべてのクライアントでメソッドを呼び出しますCalls a method on all connected clients except for the specified connections |
Client |
特定の接続されたクライアントでメソッドを呼び出しますCalls a method on a specific connected client |
Clients |
特定の接続されたクライアントでメソッドを呼び出しますCalls a method on specific connected clients |
Group |
指定されたグループ内のすべての接続でメソッドを呼び出しますCalls a method on all connections in the specified group |
GroupExcept |
指定された接続を除く、指定されたグループ内のすべての接続でメソッドを呼び出します。Calls a method on all connections in the specified group, except the specified connections |
Groups |
複数の接続グループに対してメソッドを呼び出します。Calls a method on multiple groups of connections |
OthersInGroup |
ハブメソッドを呼び出したクライアントを除く、接続のグループでメソッドを呼び出します。Calls a method on a group of connections, excluding the client that invoked the hub method |
User |
特定のユーザーに関連付けられているすべての接続でメソッドを呼び出しますCalls a method on all connections associated with a specific user |
Users |
指定されたユーザーに関連付けられているすべての接続でメソッドを呼び出しますCalls a method on all connections associated with the specified users |
前の表の各プロパティまたはメソッドは、メソッドを使用してオブジェクトを返し SendAsync
ます。Each property or method in the preceding tables returns an object with a SendAsync
method. メソッドを使用すると、 SendAsync
クライアントメソッドの名前とパラメーターを指定して呼び出すことができます。The SendAsync
method allows you to supply the name and parameters of the client method to call.
クライアントへのメッセージの送信Send messages to clients
特定のクライアントに対する呼び出しを行うには、オブジェクトのプロパティを使用し Clients
ます。To make calls to specific clients, use the properties of the Clients
object. 次の例には、3つのハブメソッドがあります。In the following example, there are three Hub methods:
SendMessage
を使用して、接続されているすべてのクライアントにメッセージを送信しClients.All
ます。SendMessage
sends a message to all connected clients, usingClients.All
.SendMessageToCaller
を使用して、メッセージを呼び出し元に返信しClients.Caller
ます。SendMessageToCaller
sends a message back to the caller, usingClients.Caller
.SendMessageToGroups
グループ内のすべてのクライアントにメッセージを送信しSignalR Users
ます。SendMessageToGroups
sends a message to all clients in theSignalR Users
group.
public Task SendMessage(string user, string message)
{
return Clients.All.SendAsync("ReceiveMessage", user, message);
}
public Task SendMessageToCaller(string user, string message)
{
return Clients.Caller.SendAsync("ReceiveMessage", user, message);
}
public Task SendMessageToGroup(string user, string message)
{
return Clients.Group("SignalR Users").SendAsync("ReceiveMessage", user, message);
}
厳密に型指定されたハブStrongly typed hubs
を使用する場合の欠点 SendAsync
は、呼び出されるクライアントメソッドを指定するマジック文字列に依存することです。A drawback of using SendAsync
is that it relies on a magic string to specify the client method to be called. これにより、メソッド名のスペルが間違っている場合、またはクライアントに存在しない場合、コードは実行時エラーになります。This leaves code open to runtime errors if the method name is misspelled or missing from the client.
を使用する代わりに、を使用してを SendAsync
厳密に型にする方法も Hub
Hub<T> あります。An alternative to using SendAsync
is to strongly type the Hub
with Hub<T>. 次の例では、 ChatHub
クライアントメソッドがというインターフェイスに抽出されてい IChatClient
ます。In the following example, the ChatHub
client methods have been extracted out into an interface called IChatClient
.
public interface IChatClient
{
Task ReceiveMessage(string user, string message);
}
このインターフェイスは、前の例をリファクターするために使用でき ChatHub
ます。This interface can be used to refactor the preceding ChatHub
example.
public class StronglyTypedChatHub : Hub<IChatClient>
{
public async Task SendMessage(string user, string message)
{
await Clients.All.ReceiveMessage(user, message);
}
public Task SendMessageToCaller(string user, string message)
{
return Clients.Caller.ReceiveMessage(user, message);
}
}
を使用すると Hub<IChatClient>
、クライアントメソッドのコンパイル時チェックが有効になります。Using Hub<IChatClient>
enables compile-time checking of the client methods. これにより、 Hub<T>
は、インターフェイスで定義されたメソッドへのアクセスのみを提供できるため、マジック文字列を使用した場合に発生する問題を回避できます。This prevents issues caused by using magic strings, since Hub<T>
can only provide access to the methods defined in the interface.
厳密に型指定されたを使用 Hub<T>
すると、を使用することができなくなり SendAsync
ます。Using a strongly typed Hub<T>
disables the ability to use SendAsync
. インターフェイスで定義されているメソッドは、引き続き非同期として定義できます。Any methods defined on the interface can still be defined as asynchronous. 実際、これらの各メソッドはを返す必要があり Task
ます。In fact, each of these methods should return a Task
. これはインターフェイスであるため、キーワードを使用しないで async
ください。Since it's an interface, don't use the async
keyword. 次に例を示します。For example:
public interface IClient
{
Task ClientMethod();
}
注意
この Async
サフィックスは、メソッド名から削除されません。The Async
suffix isn't stripped from the method name. クライアントメソッドがで定義されていない場合は .on('MyMethodAsync')
、を MyMethodAsync
名前として使用しないでください。Unless your client method is defined with .on('MyMethodAsync')
, you shouldn't use MyMethodAsync
as a name.
ハブメソッドの名前を変更するChange the name of a hub method
既定では、サーバーハブのメソッド名は .NET メソッドの名前です。By default, a server hub method name is the name of the .NET method. ただし、 HubMethodName 属性を使用してこの既定値を変更し、メソッドの名前を手動で指定することができます。However, you can use the HubMethodName attribute to change this default and manually specify a name for the method. クライアントは、メソッドを呼び出すときに、.NET メソッド名の代わりにこの名前を使用する必要があります。The client should use this name, instead of the .NET method name, when invoking the method.
[HubMethodName("SendMessageToUser")]
public Task DirectMessage(string user, string message)
{
return Clients.User(user).SendAsync("ReceiveMessage", user, message);
}
接続のイベントを処理するHandle events for a connection
SignalRHUB API は、 OnConnectedAsync
接続の OnDisconnectedAsync
管理と追跡のためのおよび仮想メソッドを提供します。The SignalR Hubs API provides the OnConnectedAsync
and OnDisconnectedAsync
virtual methods to manage and track connections. OnConnectedAsync
仮想メソッドを上書きして、クライアントがハブに接続したときにアクションを実行します (グループへの追加など)。Override the OnConnectedAsync
virtual method to perform actions when a client connects to the Hub, such as adding it to a group.
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnConnectedAsync();
}
OnDisconnectedAsync
クライアントの接続が切断されたときにアクションを実行するには、仮想メソッドをオーバーライドします。Override the OnDisconnectedAsync
virtual method to perform actions when a client disconnects. クライアントが意図的に (たとえば、を呼び出すことによって) 切断された場合、パラメーターはになり connection.stop()
exception
null
ます。If the client disconnects intentionally (by calling connection.stop()
, for example), the exception
parameter will be null
. ただし、エラー (ネットワークエラーなど) が原因でクライアントが切断された場合、パラメーターにはエラーを exception
説明する例外が含まれます。However, if the client is disconnected due to an error (such as a network failure), the exception
parameter will contain an exception describing the failure.
public override async Task OnDisconnectedAsync(Exception exception)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnDisconnectedAsync(exception);
}
警告
セキュリティ警告: を公開すると ConnectionId
、 SignalR サーバーまたはクライアントのバージョンが2.2 またはそれ以前 ASP.NET Core 場合、悪意のある偽装が発生する可能性があります。Security warning: Exposing ConnectionId
can lead to malicious impersonation if the SignalR server or client version is ASP.NET Core 2.2 or earlier.
エラーの処理Handle errors
ハブメソッドでスローされた例外は、メソッドを呼び出したクライアントに送信されます。Exceptions thrown in your hub methods are sent to the client that invoked the method. JavaScript クライアントでは、 invoke
メソッドは javascript の 約束を返します。On the JavaScript client, the invoke
method returns a JavaScript Promise. クライアントは、を使用して promise にアタッチされたハンドラーでエラーを受信すると catch
、それを呼び出し、JavaScript オブジェクトとして渡され Error
ます。When the client receives an error with a handler attached to the promise using catch
, it's invoked and passed as a JavaScript Error
object.
connection.invoke("SendMessage", user, message).catch(err => console.error(err));
ハブが例外をスローした場合、接続は閉じられません。If your Hub throws an exception, connections aren't closed. 既定では、は、 SignalR 一般的なエラーメッセージをクライアントに返します。By default, SignalR returns a generic error message to the client. 次に例を示します。For example:
Microsoft.AspNetCore.SignalR.HubException: An unexpected error occurred invoking 'MethodName' on the server.
予期しない例外には、データベース接続が失敗したときにトリガーされる例外のデータベースサーバーの名前など、重要な情報が含まれていることがよくあります。Unexpected exceptions often contain sensitive information, such as the name of a database server in an exception triggered when the database connection fails. SignalR では、これらの詳細なエラーメッセージは既定でセキュリティ対策として公開されません。SignalR doesn't expose these detailed error messages by default as a security measure. 例外の詳細が抑制される理由の詳細については、「 セキュリティに関する考慮事項 」を参照してください。See the Security considerations article for more information on why exception details are suppressed.
クライアントに伝達する必要のある 例外的な条件 がある場合は、クラスを使用でき HubException
ます。If you have an exceptional condition you do want to propagate to the client, you can use the HubException
class. ハブメソッドからをスローすると HubException
、 SignalR は 、メッセージ全体を未変更のままクライアントに送信します。If you throw a HubException
from your hub method, SignalR will send the entire message to the client, unmodified.
public Task ThrowException()
{
throw new HubException("This error will be sent to the client!");
}
注意
SignalR では、 Message
例外のプロパティのみがクライアントに送信されます。SignalR only sends the Message
property of the exception to the client. 例外のスタックトレースおよびその他のプロパティは、クライアントでは使用できません。The stack trace and other properties on the exception aren't available to the client.