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: PreviousRetryCount
a 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í Task
asynchronní 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);
}