Verwenden von Hubs in SignalR für ASP.net CoreUse hubs in SignalR for ASP.NET Core

Von Rachel Appel und Kevin GriffinBy Rachel Appel and Kevin Griffin

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)View or download sample code (how to download)

Was ist ein SignalR Hub?What is a SignalR hub

Die SignalR Hubs-API ermöglicht es Ihnen, Methoden auf verbundenen Clients vom Server aus aufzurufen.The SignalR Hubs API enables you to call methods on connected clients from the server. Im Servercode definieren Sie Methoden, die vom Client aufgerufen werden.In the server code, you define methods that are called by client. Im Client Code definieren Sie Methoden, die vom Server aufgerufen werden.In the client code, you define methods that are called from the server. SignalR kümmert sich um alles hinter den Kulissen, das die Kommunikation zwischen Client und Server und Server-zu-Client-Kommunikation in Echtzeit ermöglicht.SignalR takes care of everything behind the scenes that makes real-time client-to-server and server-to-client communications possible.

SignalRHubs konfigurierenConfigure SignalR hubs

Die SignalR Middleware erfordert einige Dienste, die durch den Aufruf von konfiguriert werden services.AddSignalR .The SignalR middleware requires some services, which are configured by calling services.AddSignalR.

services.AddSignalR();

Wenn SignalR Sie einer ASP.net Core-App Funktionen hinzufügen, richten Sie SignalR die Routen ein, indem Sie endpoint.MapHub im Startup.Configure Rückruf der Methode aufrufen 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");
});

Wenn SignalR Sie einer ASP.net Core-App Funktionen hinzufügen, richten Sie SignalR die Routen durch Aufrufen von app.UseSignalR in der- Startup.Configure Methode ein.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");
});

Erstellen und Verwenden von HubsCreate and use hubs

Erstellen Sie einen Hub, indem Sie eine Klasse deklarieren, die von erbt Hub , und Ihr öffentliche Methoden hinzufügen.Create a hub by declaring a class that inherits from Hub, and add public methods to it. Clients können Methoden aufzurufen, die als definiert sind 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);
    }
}

Sie können einen Rückgabetyp und Parameter, einschließlich komplexer Typen und Arrays, wie in jeder beliebigen c#-Methode angeben.You can specify a return type and parameters, including complex types and arrays, as you would in any C# method. SignalR verarbeitet die Serialisierung und Deserialisierung komplexer Objekte und Arrays in ihren Parametern und Rückgabe Werten.SignalR handles the serialization and deserialization of complex objects and arrays in your parameters and return values.

Hinweis

Hubs sind flüchtig:Hubs are transient:

  • Speichern Sie den Zustand nicht in einer Eigenschaft der Hub-Klasse.Don't store state in a property on the hub class. Jeder Hub-Methodenaufrufe wird auf einer neuen Hub-Instanz ausgeführt.Every hub method call is executed on a new hub instance.
  • Verwenden Sie await , wenn Sie asynchrone Methoden aufrufen, die vom Hub abhängen, der aktiv bleibt.Use await when calling asynchronous methods that depend on the hub staying alive. Beispielsweise kann eine Methode wie z. b. Clients.All.SendAsync(...) fehlschlagen, wenn Sie ohne aufgerufen wird await und die Hub-Methode vor Abschluss abgeschlossen wird 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.

Das Kontext ObjektThe Context object

Die- Hub Klasse verfügt über eine- Context Eigenschaft, die die folgenden Eigenschaften mit Informationen über die Verbindung enthält:The Hub class has a Context property that contains the following properties with information about the connection:

EigenschaftProperty BeschreibungDescription
ConnectionId Ruft die eindeutige ID für die Verbindung ab, die von zugewiesen wird SignalR .Gets the unique ID for the connection, assigned by SignalR. Es gibt eine Verbindungs-ID für jede Verbindung.There is one connection ID for each connection.
UserIdentifier Ruft den Benutzer Bezeichnerab.Gets the user identifier. Standardmäßig SignalR verwendet die ClaimTypes.NameIdentifier aus der, die ClaimsPrincipal der Verbindung zugeordnet ist, als Benutzer Bezeichner.By default, SignalR uses the ClaimTypes.NameIdentifier from the ClaimsPrincipal associated with the connection as the user identifier.
User Ruft den ab, der ClaimsPrincipal dem aktuellen Benutzer zugeordnet ist.Gets the ClaimsPrincipal associated with the current user.
Items Ruft eine Schlüssel-/Wert-Auflistung ab, die verwendet werden kann, um Daten innerhalb des Gültigkeits Bereichs dieser Verbindung freizugeben.Gets a key/value collection that can be used to share data within the scope of this connection. Die Daten können in dieser Sammlung gespeichert werden, und Sie werden für die Verbindung über verschiedene hubmethoden Aufrufe beibehalten.Data can be stored in this collection and it will persist for the connection across different hub method invocations.
Features Ruft die Auflistung der Funktionen ab, die für die Verbindung verfügbar sind.Gets the collection of features available on the connection. Diese Sammlung wird in den meisten Szenarien nicht benötigt, sodass Sie noch nicht ausführlich dokumentiert wird.For now, this collection isn't needed in most scenarios, so it isn't documented in detail yet.
ConnectionAborted Ruft ein ab CancellationToken , das benachrichtigt, wenn die Verbindung abgebrochen wird.Gets a CancellationToken that notifies when the connection is aborted.

Hub.Context enthält auch die folgenden Methoden:Hub.Context also contains the following methods:

MethodeMethod BeschreibungDescription
GetHttpContext Gibt den HttpContext für die Verbindung zurück, oder, null Wenn die Verbindung nicht mit einer HTTP-Anforderung verknüpft ist.Returns the HttpContext for the connection, or null if the connection is not associated with an HTTP request. Für http-Verbindungen können Sie diese Methode verwenden, um Informationen wie HTTP-Header und Abfrage Zeichenfolgen zu erhalten.For HTTP connections, you can use this method to get information such as HTTP headers and query strings.
Abort Bricht die Verbindung ab.Aborts the connection.

Das Client-ObjektThe Clients object

Die- Hub Klasse verfügt über eine- Clients Eigenschaft, die die folgenden Eigenschaften für die Kommunikation zwischen Server und Client enthält:The Hub class has a Clients property that contains the following properties for communication between server and client:

EigenschaftProperty BeschreibungDescription
All Ruft eine Methode auf allen verbundenen Clients auf.Calls a method on all connected clients
Caller Ruft eine Methode auf dem Client auf, der die Hub-Methode aufgerufen hat.Calls a method on the client that invoked the hub method
Others Ruft eine Methode auf allen verbundenen Clients mit Ausnahme des Clients auf, der die Methode aufgerufen hat.Calls a method on all connected clients except the client that invoked the method

Hub.Clients enthält auch die folgenden Methoden:Hub.Clients also contains the following methods:

MethodeMethod BeschreibungDescription
AllExcept Ruft eine Methode auf allen verbundenen Clients mit Ausnahme der angegebenen Verbindungen auf.Calls a method on all connected clients except for the specified connections
Client Ruft eine Methode auf einem bestimmten verbundenen Client auf.Calls a method on a specific connected client
Clients Ruft eine Methode auf bestimmten verbundenen Clients auf.Calls a method on specific connected clients
Group Ruft eine Methode für alle Verbindungen in der angegebenen Gruppe auf.Calls a method on all connections in the specified group
GroupExcept Ruft eine Methode für alle Verbindungen in der angegebenen Gruppe mit Ausnahme der angegebenen Verbindungen auf.Calls a method on all connections in the specified group, except the specified connections
Groups Ruft eine Methode für mehrere Gruppen von Verbindungen auf.Calls a method on multiple groups of connections
OthersInGroup Ruft eine Methode für eine Gruppe von Verbindungen auf, ausgenommen des Clients, der die Hub-Methode aufgerufen hat.Calls a method on a group of connections, excluding the client that invoked the hub method
User Ruft eine Methode für alle Verbindungen auf, die einem bestimmten Benutzer zugeordnet sind.Calls a method on all connections associated with a specific user
Users Ruft für alle Verbindungen, die den angegebenen Benutzern zugeordnet sind, eine Methode auf.Calls a method on all connections associated with the specified users

Jede Eigenschaft oder Methode in den vorangehenden Tabellen gibt ein-Objekt mit einer- SendAsync Methode zurück.Each property or method in the preceding tables returns an object with a SendAsync method. Mit der SendAsync -Methode können Sie den Namen und die Parameter der aufzurufenden Client Methode angeben.The SendAsync method allows you to supply the name and parameters of the client method to call.

Senden von Nachrichten an ClientsSend messages to clients

Um Aufrufe an bestimmte Clients durchführen zu können, verwenden Sie die Eigenschaften des- Clients Objekts.To make calls to specific clients, use the properties of the Clients object. Im folgenden Beispiel gibt es drei hubmethoden:In the following example, there are three Hub methods:

  • SendMessage sendet mithilfe von eine Nachricht an alle verbundenen Clients Clients.All .SendMessage sends a message to all connected clients, using Clients.All.
  • SendMessageToCaller sendet mithilfe von eine Nachricht an den Aufrufer zurück Clients.Caller .SendMessageToCaller sends a message back to the caller, using Clients.Caller.
  • SendMessageToGroups sendet eine Nachricht an alle Clients in der SignalR Users Gruppe.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);
}

Stark typisierte HubsStrongly typed hubs

Ein Nachteil von der Verwendung von SendAsync besteht darin, dass eine magische Zeichenfolge verwendet wird, um die aufzurufende Client Methode anzugeben.A drawback of using SendAsync is that it relies on a magic string to specify the client method to be called. Dadurch bleibt der Code für Laufzeitfehler geöffnet, wenn der Methodenname falsch geschrieben wurde oder auf dem Client fehlt.This leaves code open to runtime errors if the method name is misspelled or missing from the client.

Eine Alternative zur Verwendung von SendAsync ist die starke Typverwendung von Hub mit Hub<T> .An alternative to using SendAsync is to strongly type the Hub with Hub<T>. Im folgenden Beispiel wurden die ChatHub Client Methoden in eine Schnittstelle namens extrahiert 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);
}

Diese Schnittstelle kann verwendet werden, um das vorherige Beispiel zu umgestalten 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>Die Verwendung von ermöglicht die Überprüfung der Client Methoden über die Kompilierzeit.Using Hub<IChatClient> enables compile-time checking of the client methods. Dies verhindert Probleme, die durch die Verwendung von magischen Zeichen folgen verursacht werden, da Hub<T> nur den Zugriff auf die in der-Schnittstelle definierten Methoden ermöglicht.This prevents issues caused by using magic strings, since Hub<T> can only provide access to the methods defined in the interface.

Durch die Verwendung eines stark typisierten wird Hub<T> die Möglichkeit zur Verwendung von deaktiviert SendAsync .Using a strongly typed Hub<T> disables the ability to use SendAsync. Alle für die Schnittstelle definierten Methoden können weiterhin als asynchron definiert werden.Any methods defined on the interface can still be defined as asynchronous. Tatsächlich sollte jede dieser Methoden eine zurückgeben Task .In fact, each of these methods should return a Task. Da es sich um eine Schnittstelle handelt, verwenden Sie das async Schlüsselwort nicht.Since it's an interface, don't use the async keyword. Zum Beispiel:For example:

public interface IClient
{
    Task ClientMethod();
}

Hinweis

Das Async Suffix wird nicht aus dem Methodennamen entfernt.The Async suffix isn't stripped from the method name. Wenn die Client Methode nicht mit definiert ist .on('MyMethodAsync') , sollten Sie nicht MyMethodAsync als Namen verwenden.Unless your client method is defined with .on('MyMethodAsync'), you shouldn't use MyMethodAsync as a name.

Ändern des Namens einer Hub-MethodeChange the name of a hub method

Standardmäßig ist ein serverhub-Methodenname der Name der .NET-Methode.By default, a server hub method name is the name of the .NET method. Sie können jedoch das hubmethodname -Attribut verwenden, um diesen Standardwert zu ändern und manuell einen Namen für die Methode anzugeben.However, you can use the HubMethodName attribute to change this default and manually specify a name for the method. Der Client sollte beim Aufrufen der-Methode anstelle des .NET-Methoden namens diesen Namen verwenden.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);
}

Behandeln von Ereignissen für eine VerbindungHandle events for a connection

Die SignalR Hubs-API stellt OnConnectedAsync die OnDisconnectedAsync virtuellen Methoden und zum Verwalten und Nachverfolgen von Verbindungen bereit.The SignalR Hubs API provides the OnConnectedAsync and OnDisconnectedAsync virtual methods to manage and track connections. Überschreiben OnConnectedAsync Sie die virtuelle Methode, um Aktionen auszuführen, wenn ein Client eine Verbindung mit dem Hub herstellt, z. b. das Hinzufügen zu einer Gruppe.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();
}

Überschreiben OnDisconnectedAsync Sie die virtuelle Methode, um Aktionen auszuführen, wenn ein Client die Verbindung trennt.Override the OnDisconnectedAsync virtual method to perform actions when a client disconnects. Wenn der Client die Verbindung absichtlich trennt (z. b. durch Aufrufen von connection.stop() ), wird der- exception Parameter verwendet null .If the client disconnects intentionally (by calling connection.stop(), for example), the exception parameter will be null. Wenn der Client jedoch aufgrund eines Fehlers (z. b. eines Netzwerk Fehlers) getrennt wird, enthält der- exception Parameter eine Ausnahme, die den Fehler beschreibt.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);
}

Warnung

Sicherheitswarnung: das verfügbar machen von ConnectionId kann zu böswilligem Identitätswechsel führen, wenn die signalr-Server-oder-Client Version ASP.net Core 2,2 oder früher ist.Security warning: Exposing ConnectionId can lead to malicious impersonation if the SignalR server or client version is ASP.NET Core 2.2 or earlier.

Behandeln von FehlernHandle errors

Ausnahmen, die in ihren hubmethoden ausgelöst werden, werden an den Client gesendet, der die Methode aufgerufen hat.Exceptions thrown in your hub methods are sent to the client that invoked the method. Auf dem JavaScript-Client invoke gibt die Methode eine JavaScript-Zusagezurück.On the JavaScript client, the invoke method returns a JavaScript Promise. Wenn der Client einen Fehler mit einem Handler empfängt, der mithilfe von verbunden catch ist, wird er aufgerufen und als JavaScript- Error Objekt übermittelt.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));

Wenn Ihr Hub eine Ausnahme auslöst, werden die Verbindungen nicht geschlossen.If your Hub throws an exception, connections aren't closed. Standardmäßig wird SignalR eine generische Fehlermeldung an den Client zurückgegeben.By default, SignalR returns a generic error message to the client. Zum Beispiel:For example:

Microsoft.AspNetCore.SignalR.HubException: An unexpected error occurred invoking 'MethodName' on the server.

Unerwartete Ausnahmen enthalten häufig vertrauliche Informationen, wie z. b. den Namen eines Datenbankservers in einer Ausnahme, die ausgelöst wird, wenn die Datenbankverbindung fehlschlägt.Unexpected exceptions often contain sensitive information, such as the name of a database server in an exception triggered when the database connection fails. SignalR macht diese detaillierten Fehlermeldungen standardmäßig nicht als Sicherheitsmaßnahme verfügbar.SignalR doesn't expose these detailed error messages by default as a security measure. Weitere Informationen dazu, warum Ausnahme Details unterdrückt werden, finden Sie im Artikel Sicherheitsüberlegungen .See the Security considerations article for more information on why exception details are suppressed.

Wenn Sie eine Ausnahme Bedingung haben, die Sie an den Client weiter geben möchten, können Sie die- HubException Klasse verwenden.If you have an exceptional condition you do want to propagate to the client, you can use the HubException class. Wenn Sie einen HubException aus ihrer Hub-Methode auslösen, SignalR will sendet die gesamte Nachricht unverändert an den Client.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!");
}

Hinweis

SignalR sendet die- Message Eigenschaft der Ausnahme nur an den Client.SignalR only sends the Message property of the exception to the client. Die Stapel Überwachung und andere Eigenschaften der Ausnahme sind für den Client nicht verfügbar.The stack trace and other properties on the exception aren't available to the client.