のハブを 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.AddSignalRThe 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ハブをキープアライブに依存する非同期メソッドを呼び出すときに使用します。Use await when calling asynchronous methods that depend on the hub staying alive. たとえば、を Clients.All.SendAsync(...) 指定せずに呼び出され、 await ハブメソッドが終了する前に完了した場合、などのメソッドは失敗する可能性が SendAsync あります。For example, a method such as Clients.All.SendAsync(...) can fail if it's called without await and the hub method completes before SendAsync 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, using Clients.All.
  • SendMessageToCaller を使用して、メッセージを呼び出し元に返信し Clients.Caller ます。SendMessageToCaller sends a message back to the caller, using Clients.Caller.
  • SendMessageToGroups グループ内のすべてのクライアントにメッセージを送信し SignalR Users ます。SendMessageToGroups sends a message to all clients in the SignalR 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.