ASP.net Core SignalR .NET-ClientASP.NET Core SignalR .NET Client

Mit der ASP.net Core SignalR .NET-Client Bibliothek können Sie über SignalR .net-apps mit Hubs kommunizieren.The ASP.NET Core SignalR .NET client library lets you communicate with SignalR hubs from .NET apps.

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

Das Codebeispiel in diesem Artikel ist eine WPF-App, die den ASP.net Core SignalR .NET-Client verwendet.The code sample in this article is a WPF app that uses the ASP.NET Core SignalR .NET client.

Installieren des SignalR .NET-Client PaketsInstall the SignalR .NET client package

Microsoft. aspnetcore. SignalR . Das Client Paket ist für .NET-Clients erforderlich, um eine Verbindung mit SignalR Hubs herzustellen.The Microsoft.AspNetCore.SignalR.Client package is required for .NET clients to connect to SignalR hubs.

Um die Client Bibliothek zu installieren, führen Sie den folgenden Befehl im Fenster Paket-Manager-Konsole aus:To install the client library, run the following command in the Package Manager Console window:

Install-Package Microsoft.AspNetCore.SignalR.Client

Herstellen einer Verbindung mit einem HubConnect to a hub

Erstellen Sie einen, und rufen Sie auf, um eine Verbindung herzustellen HubConnectionBuilder Build .To establish a connection, create a HubConnectionBuilder and call Build. Die Hub-URL, das Protokoll, der Transporttyp, die Protokollebene, Header und andere Optionen können beim Herstellen einer Verbindung konfiguriert werden.The hub URL, protocol, transport type, log level, headers, and other options can be configured while building a connection. Konfigurieren Sie alle erforderlichen Optionen, indem Sie eine der HubConnectionBuilder Methoden in einfügen Build .Configure any required options by inserting any of the HubConnectionBuilder methods into Build. Starten Sie die Verbindung mit StartAsync .Start the connection with StartAsync.

using System;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.AspNetCore.SignalR.Client;

namespace SignalRChatClient
{
    public partial class MainWindow : Window
    {
        HubConnection connection;
        public MainWindow()
        {
            InitializeComponent();

            connection = new HubConnectionBuilder()
                .WithUrl("http://localhost:53353/ChatHub")
                .Build();

            connection.Closed += async (error) =>
            {
                await Task.Delay(new Random().Next(0,5) * 1000);
                await connection.StartAsync();
            };
        }

        private async void connectButton_Click(object sender, RoutedEventArgs e)
        {
            connection.On<string, string>("ReceiveMessage", (user, message) =>
            {
                this.Dispatcher.Invoke(() =>
                {
                   var newMessage = $"{user}: {message}";
                   messagesList.Items.Add(newMessage);
                });
            });

            try
            {
                await connection.StartAsync();
                messagesList.Items.Add("Connection started");
                connectButton.IsEnabled = false;
                sendButton.IsEnabled = true;
            }
            catch (Exception ex)
            {
                messagesList.Items.Add(ex.Message);
            }
        }

        private async void sendButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                await connection.InvokeAsync("SendMessage", 
                    userTextBox.Text, messageTextBox.Text);
            }
            catch (Exception ex)
            {                
                messagesList.Items.Add(ex.Message);                
            }
        }
    }
}

Handle für verlorene VerbindungHandle lost connection

Automatisch wiederherstellen der VerbindungAutomatically reconnect

Der HubConnection kann so konfiguriert werden, dass mithilfe der-Methode in automatisch erneut eine Verbindung hergestellt wird WithAutomaticReconnect HubConnectionBuilder .The HubConnection can be configured to automatically reconnect using the WithAutomaticReconnect method on the HubConnectionBuilder. Standardmäßig wird die Verbindung nicht automatisch wieder hergestellt.It won't automatically reconnect by default.

HubConnection connection= new HubConnectionBuilder()
    .WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
    .WithAutomaticReconnect()
    .Build();

Ohne Parameter WithAutomaticReconnect() konfiguriert den Client so, dass 0, 2, 10 und 30 Sekunden gewartet wird, bevor versucht wird, jeden erneuten Verbindungsversuch durchzusetzen, der nach vier fehlgeschlagenen Versuchen angehalten wird.Without any parameters, WithAutomaticReconnect() configures the client to wait 0, 2, 10, and 30 seconds respectively before trying each reconnect attempt, stopping after four failed attempts.

Vor dem Starten von Wiederholungs versuchen wechselt der HubConnection in den HubConnectionState.Reconnecting -Zustand, und das- Reconnecting Ereignis wird ausgelöst.Before starting any reconnect attempts, the HubConnection will transition to the HubConnectionState.Reconnecting state and fire the Reconnecting event. Dies bietet die Möglichkeit, die Benutzer zu warnen, dass die Verbindung unterbrochen wurde, und Benutzeroberflächen Elemente zu deaktivieren.This provides an opportunity to warn users that the connection has been lost and to disable UI elements. Nicht interaktive Apps können Nachrichten in die Warteschlange einreihen oder löschen.Non-interactive apps can start queuing or dropping messages.

connection.Reconnecting += error =>
{
    Debug.Assert(connection.State == HubConnectionState.Reconnecting);

    // Notify users the connection was lost and the client is reconnecting.
    // Start queuing or dropping messages.

    return Task.CompletedTask;
};

Wenn der Client innerhalb der ersten vier Versuche erfolgreich erneut eine Verbindung herstellt, wechselt HubConnection zurück in den Connected -Zustand und löst das- Reconnected Ereignis aus.If the client successfully reconnects within its first four attempts, the HubConnection will transition back to the Connected state and fire the Reconnected event. Dies bietet die Möglichkeit, den Benutzern mitzuteilen, dass die Verbindung wieder hergestellt wurde, und alle Nachrichten in der Warteschlange aus der Warteschlange entferntThis provides an opportunity to inform users the connection has been reestablished and dequeue any queued messages.

Da die Verbindung mit dem Server vollständig neu ist, ConnectionId wird den Ereignis Handlern eine neue bereitgestellt Reconnected .Since the connection looks entirely new to the server, a new ConnectionId will be provided to the Reconnected event handlers.

Warnung

Der Reconnected -Parameter des Ereignis Handlers ist connectionId NULL, wenn der HubConnection zum über springen der Aushandlungkonfiguriert wurde.The Reconnected event handler's connectionId parameter will be null if the HubConnection was configured to skip negotiation.

connection.Reconnected += connectionId =>
{
    Debug.Assert(connection.State == HubConnectionState.Connected);

    // Notify users the connection was reestablished.
    // Start dequeuing messages queued while reconnecting if any.

    return Task.CompletedTask;
};

WithAutomaticReconnect() konfiguriert nicht HubConnection , um anfängliche Start Fehler zu wiederholen, sodass Start Fehler manuell behandelt werden müssen:WithAutomaticReconnect() won't configure the HubConnection to retry initial start failures, so start failures need to be handled manually:

public static async Task<bool> ConnectWithRetryAsync(HubConnection connection, CancellationToken token)
{
    // Keep trying to until we can start or the token is canceled.
    while (true)
    {
        try
        {
            await connection.StartAsync(token);
            Debug.Assert(connection.State == HubConnectionState.Connected);
            return true;
        }
        catch when (token.IsCancellationRequested)
        {
            return false;
        }
        catch
        {
            // Failed to connect, trying again in 5000 ms.
            Debug.Assert(connection.State == HubConnectionState.Disconnected);
            await Task.Delay(5000);
        }
    }
}

Wenn der Client nicht innerhalb der ersten vier Versuche erneut eine Verbindung herstellt, wechselt HubConnection in den Disconnected -Status, und das-Ereignis wird ausgelöst Closed .If the client doesn't successfully reconnect within its first four attempts, the HubConnection will transition to the Disconnected state and fire the Closed event. Auf diese Weise können Sie versuchen, die Verbindung manuell neu zu starten oder den Benutzern mitzuteilen, dass die Verbindung dauerhaft verloren gegangen ist.This provides an opportunity to attempt to restart the connection manually or inform users the connection has been permanently lost.

connection.Closed += error =>
{
    Debug.Assert(connection.State == HubConnectionState.Disconnected);

    // Notify users the connection has been closed or manually try to restart the connection.

    return Task.CompletedTask;
};

Um eine benutzerdefinierte Anzahl von Wiederholungs versuchen zu konfigurieren, bevor die Verbindung getrennt wird, oder um die zeitliche Verbindung wiederherzustellen, WithAutomaticReconnect akzeptiert ein Array von Zahlen, das die Verzögerung in Millisekunden angibt, die gewartet werden soll, bevor die einzelnen Wiederholungs Versuche gestartet werden.In order to configure a custom number of reconnect attempts before disconnecting or change the reconnect timing, WithAutomaticReconnect accepts an array of numbers representing the delay in milliseconds to wait before starting each reconnect attempt.

HubConnection connection= new HubConnectionBuilder()
    .WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
    .WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.Zero, TimeSpan.FromSeconds(10) })
    .Build();

    // .WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30) }) yields the default behavior.

Im vorangehenden Beispiel wird der so konfiguriert HubConnection , dass nach dem Verlust der Verbindung erneut versucht wird, die Verbindung herzustellen.The preceding example configures the HubConnection to start attempting reconnects immediately after the connection is lost. Dies gilt auch für die Standardkonfiguration.This is also true for the default configuration.

Wenn der erste Wiederholungsversuch fehlschlägt, wird der zweite Wiederholungsversuch auch sofort gestartet, anstatt zwei Sekunden zu warten, wie in der Standardkonfiguration.If the first reconnect attempt fails, the second reconnect attempt will also start immediately instead of waiting 2 seconds like it would in the default configuration.

Wenn der zweite Wiederholungsversuch fehlschlägt, wird der dritte Versuch der erneuten Verbindungs Herstellung in 10 Sekunden gestartet. Dies entspricht der Standardkonfiguration.If the second reconnect attempt fails, the third reconnect attempt will start in 10 seconds which is again like the default configuration.

Das benutzerdefinierte Verhalten weicht dann erneut vom Standardverhalten ab, indem nach dem dritten Wiederholungsversuch der Verbindung angehalten wird.The custom behavior then diverges again from the default behavior by stopping after the third reconnect attempt failure. In der Standardkonfiguration gibt es einen weiteren erneuten Verbindungsversuch in weiteren 30 Sekunden.In the default configuration there would be one more reconnect attempt in another 30 seconds.

Wenn Sie eine noch größere Kontrolle über die zeitliche Steuerung und die Anzahl der automatischen Wiederholungs Versuche wünschen, WithAutomaticReconnect akzeptiert ein Objekt, das die- IRetryPolicy Schnittstelle implementiert, die über eine einzige Methode mit dem Namen verfügt NextRetryDelay .If you want even more control over the timing and number of automatic reconnect attempts, WithAutomaticReconnect accepts an object implementing the IRetryPolicy interface, which has a single method named NextRetryDelay.

NextRetryDelay nimmt ein einzelnes Argument mit dem Typ an RetryContext .NextRetryDelay takes a single argument with the type RetryContext. RetryContextVerfügt über drei Eigenschaften: PreviousRetryCount , ElapsedTime und RetryReason , wobei es sich um ein long -, ein TimeSpan -und ein-Wert handelt Exception .The RetryContext has three properties: PreviousRetryCount, ElapsedTime and RetryReason, which are a long, a TimeSpan and an Exception respectively. Vor dem ersten Versuch, die Verbindung wiederherzustellen, sind sowohl PreviousRetryCount als auch ElapsedTime 0 (null) und die Ausnahme, die bewirkt hat, RetryReason dass die Verbindung unterbrochen wurde.Before the first reconnect attempt, both PreviousRetryCount and ElapsedTime will be zero, and the RetryReason will be the Exception that caused the connection to be lost. Nach jedem fehlgeschlagenen Wiederholungsversuch PreviousRetryCount wird um eins erhöht, ElapsedTime wird aktualisiert, um die Zeitspanne für eine erneute Verbindungs Herstellung widerzuspiegeln, und die Ausnahme, die bewirkt hat, RetryReason dass der letzte Wiederholungsversuch fehlgeschlagen ist.After each failed retry attempt, PreviousRetryCount will be incremented by one, ElapsedTime will be updated to reflect the amount of time spent reconnecting so far, and the RetryReason will be the Exception that caused the last reconnect attempt to fail.

NextRetryDelay muss entweder einen TimeSpan-Wert zurückgeben, der die Zeit angibt, die gewartet werden soll, bevor der nächste Verbindungsversuch wiederholt null wird HubConnection .NextRetryDelay must return either a TimeSpan representing the time to wait before the next reconnect attempt or null if the HubConnection should stop reconnecting.

public class RandomRetryPolicy : IRetryPolicy
{
    private readonly Random _random = new Random();

    public TimeSpan? NextRetryDelay(RetryContext retryContext)
    {
        // If we've been reconnecting for less than 60 seconds so far,
        // wait between 0 and 10 seconds before the next reconnect attempt.
        if (retryContext.ElapsedTime < TimeSpan.FromSeconds(60))
        {
            return TimeSpan.FromSeconds(_random.NextDouble() * 10);
        }
        else
        {
            // If we've been reconnecting for more than 60 seconds so far, stop reconnecting.
            return null;
        }
    }
}
HubConnection connection = new HubConnectionBuilder()
    .WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
    .WithAutomaticReconnect(new RandomRetryPolicy())
    .Build();

Alternativ dazu können Sie auch Code schreiben, mit dem der Client manuell erneut eine Verbindung herstellt, wie in Manuelles Wiederherstellen der Verbindunggezeigt.Alternatively, you can write code that will reconnect your client manually as demonstrated in Manually reconnect.

Verbindung manuell wiederherstellenManually reconnect

Warnung

Vor 3,0 wird die Verbindung des .NET-Clients für SignalR nicht automatisch wieder hergestellt.Prior to 3.0, the .NET client for SignalR doesn't automatically reconnect. Sie müssen Code schreiben, mit dem der Client manuell erneut eine Verbindung herstellt.You must write code that will reconnect your client manually.

Verwenden Sie das- Closed Ereignis, um auf eine verlorene Verbindung zu reagieren.Use the Closed event to respond to a lost connection. Beispielsweise möchten Sie möglicherweise die erneute Verbindung automatisieren.For example, you might want to automate reconnection.

Das-Ereignis erfordert einen Delegaten, der Closed einen zurückgibt, mit dem asynchroner Task Code ohne Verwendung von ausgeführt werden kann async void .The Closed event requires a delegate that returns a Task, which allows async code to run without using async void. Um die Delegatsignatur in einem Ereignishandler zu erfüllen, der Closed synchron ausgeführt wird, geben Sie Folgendes zurück Task.CompletedTask :To satisfy the delegate signature in a Closed event handler that runs synchronously, return Task.CompletedTask:

connection.Closed += (error) => {
    // Do your close logic.
    return Task.CompletedTask;
};

Der Hauptgrund für die Async-Unterstützung ist, dass Sie die Verbindung neu starten können.The main reason for the async support is so you can restart the connection. Das Starten einer Verbindung ist eine asynchrone Aktion.Starting a connection is an async action.

In einem Closed Handler, der die Verbindung neu startet, sollten Sie auf eine zufällige Verzögerung warten, um das Überladen des Servers zu verhindern, wie im folgenden Beispiel gezeigt:In a Closed handler that restarts the connection, consider waiting for some random delay to prevent overloading the server, as shown in the following example:

connection.Closed += async (error) =>
{
    await Task.Delay(new Random().Next(0,5) * 1000);
    await connection.StartAsync();
};

Hub-Methoden vom Client abrufenCall hub methods from client

InvokeAsync Ruft Methoden für den Hub auf.InvokeAsync calls methods on the hub. Übergeben Sie den Namen der Hub-Methode und alle in der Hub-Methode definierten Argumente an InvokeAsync .Pass the hub method name and any arguments defined in the hub method to InvokeAsync. SignalR ist asynchron, verwenden Sie also async und, await Wenn Sie die Aufrufe ausführen.SignalR is asynchronous, so use async and await when making the calls.

await connection.InvokeAsync("SendMessage", 
    userTextBox.Text, messageTextBox.Text);

Die InvokeAsync Methode gibt einen zurück Task , der abgeschlossen wird, wenn die Server Methode zurückgibt.The InvokeAsync method returns a Task which completes when the server method returns. Der Rückgabewert wird ggf. als Ergebnis von bereitgestellt Task .The return value, if any, is provided as the result of the Task. Alle Ausnahmen, die von der-Methode auf dem Server ausgelöst werden, führen zu einem Fehler Task .Any exceptions thrown by the method on the server produce a faulted Task. Verwenden await Sie die-Syntax, um auf den Abschluss der Server Methode und die try...catch Syntax zur Fehlerbehandlung zu warten.Use await syntax to wait for the server method to complete and try...catch syntax to handle errors.

Die SendAsync Methode gibt einen zurück, der abgeschlossen wird, Task Wenn die Nachricht an den Server gesendet wurde.The SendAsync method returns a Task which completes when the message has been sent to the server. Es wird kein Rückgabewert bereitgestellt, da dieser Task nicht wartet, bis die Server Methode abgeschlossen ist.No return value is provided since this Task doesn't wait until the server method completes. Alle Ausnahmen, die beim Senden der Nachricht auf dem Client ausgelöst werden, führen zu einem Fehler Task .Any exceptions thrown on the client while sending the message produce a faulted Task. Verwenden await try...catch Sie die Syntax und, um Sende Fehler zu behandeln.Use await and try...catch syntax to handle send errors.

Hinweis

Das Aufrufen von Hub-Methoden von einem Client wird nur unterstützt, wenn der Azure- SignalR Dienst im Standard Modus verwendet wird.Calling hub methods from a client is only supported when using the Azure SignalR Service in Default mode. Weitere Informationen finden Sie unter häufig gestellte Fragen (Azure-signalr-GitHub-Repository).For more information, see Frequently Asked Questions (azure-signalr GitHub repository).

Client Methoden aus Hub abrufenCall client methods from hub

Definieren von Methoden, die der Hub mithilfe von connection.On nach dem Aufbau aufruft, jedoch vor dem Starten der Verbindung.Define methods the hub calls using connection.On after building, but before starting the connection.

connection.On<string, string>("ReceiveMessage", (user, message) =>
{
    this.Dispatcher.Invoke(() =>
    {
       var newMessage = $"{user}: {message}";
       messagesList.Items.Add(newMessage);
    });
});

Der vorangehende Code in wird ausgeführt, connection.On Wenn der serverseitige Code ihn mit der- SendAsync Methode aufruft.The preceding code in connection.On runs when server-side code calls it using the SendAsync method.

public async Task SendMessage(string user, string message)
{
    await Clients.All.SendAsync("ReceiveMessage", user,message);
}

Fehlerbehandlung und ProtokollierungError handling and logging

Behandeln Sie Fehler mit einer try-catch-Anweisung.Handle errors with a try-catch statement. Überprüfen Exception Sie das Objekt, um die ordnungsgemäße Aktion zu bestimmen, die nach einem Fehler ausgeführt werden soll.Inspect the Exception object to determine the proper action to take after an error occurs.

try
{
    await connection.InvokeAsync("SendMessage", 
        userTextBox.Text, messageTextBox.Text);
}
catch (Exception ex)
{                
    messagesList.Items.Add(ex.Message);                
}

Zusätzliche RessourcenAdditional resources