SignalRASP.NET Core Klient .NET
Klientská ASP.NET Core SignalR .NET umožňuje komunikovat s SignalR cly z aplikací .NET.
Zobrazení nebo stažení ukázkového kódu (stažení)
Vzorový kód v tomto článku je aplikace WPF, která používá ASP.NET Core SignalR .NET.
Instalace balíčku SignalR klienta .NET
Microsoft.AspNetCore. SignalR . Aby se klienti .NET připojují k rozbočovačům, vyžaduje se SignalR klientský balíček.
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í do centra
Pokud chcete navázat připojení, vytvořte a HubConnectionBuilder 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 kterékoli z HubConnectionBuilder metod do Build . Spusťte připojení pomocí 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řipojoval WithAutomaticReconnect pomocí metody v HubConnectionBuilder . Ve výchozím nastavení se automaticky znovu 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, aby před pokusem o opětovné připojení počkal 0, 2, 10 a 30 sekund a po čtyřech WithAutomaticReconnect() neúspěšných pokusech se zastavil.
Před zahájením pokusů o opětovné připojení HubConnection se přechází do HubConnectionState.Reconnecting stavu a událost se Reconnecting vyvolá. To poskytuje možnost upozornit uživatele, že připojení bylo ztraceno, a zakázat prvky uživatelského rozhraní. Neinteraktivní aplikace mohou začít zařaovat zprávy do fronty nebo je zahazovat.
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ů, přechází zpět do stavu HubConnection Connected a vyhodí Reconnected událost. To poskytuje příležitost informovat uživatele, že připojení bylo znovu vytvořeno, a všechny zprávy zařazené do fronty se z fronty z fronty vyřadí.
Vzhledem k tomu, že připojení vypadá zcela novým serverem, bude obslužnám rutinám událostí ConnectionId Reconnected poskytnuto nové připojení.
Upozornění
Pokud byl parametr obslužné rutiny události nakonfigurovaný tak, aby přeskočoval vyjednávání, bude mít hodnotu Reconnected connectionId HubConnection null.
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 pro HubConnection opakování selhání počátečního spuštění, takže selhání 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ě znovu nepřipojí, přechází do stavu HubConnection Disconnected a událost se Closed vyhodí. To poskytuje příležitost pokusit se připojení restartovat 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;
};
Aby bylo možné nakonfigurovat vlastní počet pokusů o opětovné připojení před odpojením nebo změnou načasování opětovného připojení, přijímá pole čísel představující zpoždění v milisekundách, které se mají čekat před spuštěním každého pokusu o opětovné WithAutomaticReconnect 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 , aby se ihned po ztrátě připojení začal pokoušet HubConnection o opětovné připojení. To platí také pro výchozí konfiguraci.
Pokud první pokus o opětovné připojení selže, druhý pokus o opětovné připojení se také spustí 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 odchýlí od výchozího chování tím, že se zastaví po selhání třetího pokusu o opětovné připojení. Ve výchozí konfiguraci by během dalších 30 sekund došlo k dalšímu pokusu o opětovné připojení.
Pokud chcete mít ještě větší kontrolu nad načasováním a počtem pokusů o automatické opětovné připojení, přijme objekt implementující rozhraní, které má WithAutomaticReconnect IRetryPolicy jednu metodu s názvem NextRetryDelay .
NextRetryDelay přebírá jeden argument s typem RetryContext . Má RetryContext tři vlastnosti: PreviousRetryCount , a , což jsou , a a v uvedeném ElapsedTime RetryReason long TimeSpan Exception pořadí. Před prvním pokusem o opětovné připojení bude hodnota i nulová a hodnota bude Výjimka, která způsobila PreviousRetryCount ElapsedTime RetryReason ztrátu připojení. Po každém neúspěšným pokusu o opakování se zvýší o jeden pokus, aktualizuje se tak, aby odrážel dobu strávenou opětovným připojením, a bude to výjimka, která způsobila selhání posledního pokusu o opětovné PreviousRetryCount ElapsedTime RetryReason připojení.
NextRetryDelay musí vrátit buď TimeSpan představující čas čekání před dalším pokusem o opětovné připojení, nebo zda by měl zastavit null HubConnection opětovné připojení.
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();
Alternativně můžete napsat kód, který znovu připojí vašeho klienta ručně, jak je znázorněno v části Ruční opětovné připojení.
Ruční opětovné připojení
Upozornění
Před 3.0 se klient .NET pro automaticky znovu SignalR nepřipojí. Musíte napsat kód, který znovu připojí vašeho klienta ručně.
Pomocí události Closed 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í , který umožňuje spuštění asynchronního kódu Task bez použití async void . Pokud chcete splnit podpis delegátu v obslužné Closed 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 modifikátoru Async je restartování připojení. Spuštění připojení je asynchronní akce.
V obslužné rutině, která restartuje připojení, zvažte čekání na náhodné zpoždění, aby se zabránilo přetížení serveru, jak je znázorněno Closed v následujícím příkladu:
connection.Closed += async (error) =>
{
await Task.Delay(new Random().Next(0,5) * 1000);
await connection.StartAsync();
};
Volání metod centra z klienta
InvokeAsync volá metody v centru. Předejte metodě centra název metody a všechny argumenty definované v metodě centra InvokeAsync do . SignalR je asynchronní, proto při async await volání použijte a .
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
Metoda InvokeAsync vrátí , který se Task dokončí, když metoda serveru vrátí hodnotu . Vrácená hodnota , pokud existuje, je poskytnuta jako výsledek Task . Všechny výjimky vyvolané metodou na serveru vyprodukují chybu Task . Pomocí await syntaxe počkejte na dokončení metody serveru a try...catch syntaxi pro zpracování chyb.
Metoda vrátí , který se dokončí po odeslání zprávy SendAsync Task na server. Není k dispozici žádná návratová hodnota, Task protože nečeká, dokud se metoda serveru nedokoní. Všechny výjimky vyvolané klientem při odesílání zprávy vyprodukují chybu Task . Použití await try...catch syntaxe a ke zpracování chyb 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 nejčastějších dotazech (azure-signalr GitHub úložišti).
Volání klientských metod z centra
Definujte metody, které centrum volá connection.On po sestavení, ale před zahájení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 v se spustí, když ho kód na straně serveru connection.On zavolá pomocí SendAsync metody .
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user,message);
}
Poznámka
I když centrální strana připojení podporuje zasílání zpráv se silnými typy, klient se musí zaregistrovat pomocí obecné metody HubConnection.On s názvem metody. Příklad naleznete v tématu Hostování 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 Exception a určete správnou akci, která se má provést, když dojde k chybě.
try
{
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
}
catch (Exception ex)
{
messagesList.Items.Add(ex.Message);
}