Sdílet prostřednictvím


klient ASP.NET Core SignalR .NET

Klientská knihovna ASP.NET Core SignalR .NET umožňuje komunikovat s SignalR rozbočovači z aplikací .NET.

Zobrazení nebo stažení ukázkového kódu (postup stažení)

Vzorový kód v tomto článku je aplikace WPF, která používá klienta ASP.NET Core SignalR .NET.

SignalR Instalace balíčku klienta .NET

Microsoft.AspNetCore .SignalR. Klientský balíček se vyžaduje pro klienty .NET pro připojení k SignalR rozbočovačům.

Pokud chcete nainstalovat klientskou knihovnu, spusťte v okně konzoly Správce balíčků následující příkaz:

Install-Package Microsoft.AspNetCore.SignalR.Client

Připojení k centru

Chcete-li vytvořit připojení, vytvořte HubConnectionBuilder a zavolejte Build. Při vytváření připojení je možné nakonfigurovat adresu URL centra, protokol, typ přenosu, úroveň protokolu, hlavičky a další možnosti. Nakonfigurujte všechny požadované možnosti vložením některé z HubConnectionBuilder metod do Build. Spusťte spojení s 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);                
            }
        }
    }
}

Zpracování ztraceného připojení

Automatické opětovné připojení

Lze HubConnection nakonfigurovat tak, aby se automaticky znovu připojil pomocí WithAutomaticReconnect metody na kartě HubConnectionBuilder. Ve výchozím nastavení se automaticky nepřipojí.

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

Bez jakýchkoli parametrů nakonfiguruje klienta tak, WithAutomaticReconnect() aby čekal 0, 2, 10 a 30 sekund před pokusem o opětovné připojení a zastavil se po čtyřech neúspěšných pokusech.

Než začnete s opakovaným pokusem o připojení, HubConnection přejde se do HubConnectionState.Reconnecting stavu a událost se aktivuje Reconnecting . To poskytuje možnost upozornit uživatele, že připojení bylo ztraceno a zakázat prvky uživatelského rozhraní. Neinteraktivní aplikace můžou začít zařazovat zprávy do fronty nebo vyřazovat zprávy.

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;
};

Pokud se klient úspěšně znovu připojí během prvních čtyř pokusů, HubConnection přejde zpět do Connected stavu a aktivuje Reconnected událost. To poskytuje možnost informovat uživatele, že připojení bylo znovu publikováno a vyřazeno z fronty zpráv.

Vzhledem k tomu, že připojení na serveru vypadá zcela nové, bude obslužným rutině událostí poskytována Reconnected nováConnectionId.

Upozorňující

Parametr Reconnected obslužné rutiny connectionId události bude null, pokud HubConnection byl nakonfigurován tak, aby přeskočí vyjednávání.

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() nenakonfiguruje HubConnection opakování neúspěšných počátečních spuštění, takže chyby spuštění je potřeba zpracovat ručně:

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);
        }
    }
}

Pokud se klient během prvních čtyř pokusů úspěšně nepřipojí, HubConnection přejde do Disconnected stavu a aktivuje Closed událost. To poskytuje příležitost pokusit se restartovat připojení ručně nebo informovat uživatele, že připojení bylo trvale ztraceno.

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;
};

Pokud chcete nakonfigurovat vlastní počet pokusů o opětovné připojení před odpojením nebo změnou časování opětovného připojení, WithAutomaticReconnect přijme pole čísel představující zpoždění v milisekundách, aby se čekalo před zahájením každého pokusu o opětovné připojení.

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.

Předchozí příklad nakonfiguruje HubConnection pokus o opětovné připojení okamžitě po ztrátě připojení. To platí i pro výchozí konfiguraci.

Pokud první pokus o opětovné připojení selže, druhý pokus o opětovné připojení se spustí také okamžitě místo čekání na 2 sekundy, jako by byl ve výchozí konfiguraci.

Pokud druhý pokus o opětovné připojení selže, třetí pokus o opětovné připojení se spustí za 10 sekund, což je znovu jako výchozí konfigurace.

Vlastní chování se pak znovu liší od výchozího chování zastavením po selhání třetího pokusu o opětovné připojení. Ve výchozí konfiguraci by došlo k dalšímu pokusu o opětovné připojení za dalších 30 sekund.

Chcete-li ještě větší kontrolu nad časováním a počtem automatických pokusů o opětovné připojení, WithAutomaticReconnect přijímá objekt implementuje IRetryPolicy rozhraní, který má jednu metodu s názvem NextRetryDelay.

NextRetryDelay přebírá jeden argument s typem RetryContext. Má RetryContext tři vlastnosti: PreviousRetryCounta ElapsedTime RetryReason, které jsou long, TimeSpan a Exception v uvedeném pořadí. Před prvním opakovaným pokusem o připojení bude nula PreviousRetryCount ElapsedTime a RetryReason bude výjimkou, která způsobila ztrátu připojení. Po každém neúspěšném pokusu o PreviousRetryCount opakování se jeden zvýší o jeden, bude aktualizován tak, ElapsedTime aby odrážel dobu strávenou opětovným připojením, která dosud strávila opětovným připojením, a RetryReason bude výjimkou, která způsobila poslední pokus o opětovné připojení selhat.

NextRetryDelay Musí vrátit buď TimeSpan představující dobu čekání před dalším pokusem o opětovné připojení, nebo null pokud HubConnection by mělo přestat znovu připojovat.

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();

Případně můžete napsat kód, který klienta znovu připojí ručně, jak je znázorněno v tématu Ruční opětovné připojení.

Ruční opětovné připojení

Upozorňující

Před verzí 3.0 se klient .NET pro SignalR automaticky nepřipojí. Musíte napsat kód, který klienta znovu připojí ručně.

Closed Pomocí události můžete reagovat na ztracené připojení. Můžete například chtít automatizovat opětovné připojení.

Událost Closed vyžaduje delegáta, který vrací Taskasynchronní kód, aby běžel bez použití async void. Pokud chcete vyhovět podpisu delegáta Closed v obslužné rutině události, která běží synchronně, vraťte Task.CompletedTask:

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

Hlavním důvodem podpory asynchronních připojení je restartování připojení. Spuštění připojení je asynchronní akce.

V obslužné rutině Closed , která restartuje připojení, zvažte čekání na určité náhodné zpoždění, aby se zabránilo přetížení serveru, jak je znázorněno v následujícím příkladu:

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

Metody centra volání z klienta

InvokeAsync volá metody v centru. Předejte název metody centra a všechny argumenty definované v metodě centra do InvokeAsync. SignalR je asynchronní, takže používejte async a await při provádění volání.

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

Metoda InvokeAsync vrátí Task , která se dokončí, když metoda serveru vrátí. Vrácená hodnota, pokud existuje, je uvedena jako výsledek Task. Všechny výjimky vyvolané metodou na serveru způsobí chybu Task. Syntaxe slouží await k čekání na dokončení metody serveru a try...catch syntaxi zpracování chyb.

Metoda SendAsync vrátí Task , která se dokončí, když byla zpráva odeslána na server. Není k dispozici žádná návratová hodnota, protože nečeká Task na dokončení metody serveru. Všechny výjimky vyvolané klientem při odesílání zprávy způsobí chybu Task. Použití await a try...catch syntaxe ke zpracování chyb při odesílání

Poznámka:

Volání metod centra z klienta je podporováno pouze při použití služby Azure SignalR ve výchozím režimu. Další informace najdete v tématu Nejčastější dotazy (úložiště Azure–signalr GitHub).

Volání metod klienta z centra

Definujte metody volání centra, které používají connection.On po sestavení, ale před spuštěním připojení.

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

Předchozí kód se connection.On spustí, když ho kód na straně serveru volá pomocí SendAsync metody.

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

Poznámka:

Zatímco strana rozbočovače připojení podporuje zasílání zpráv silného typu, klient se musí zaregistrovat pomocí obecné metody HubConnection.On s názvem metody. Příklad najdete v tématu Host ASP.NET Core SignalR ve službách na pozadí.

Zpracování chyb a protokolování

Zpracování chyb pomocí příkazu try-catch Zkontrolujte objekt a Exception určete správnou akci, která se má provést po výskytu chyby.

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

Další materiály