Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Med klientbiblioteket ASP.NET Core SignalR .NET kan du kommunicera med SignalR hubbar från .NET-appar.
Visa eller ladda ned exempelkod (hur du laddar ned)
Kodexemplet i den här artikeln är en WPF-app som använder ASP.NET Core SignalR .NET-klienten.
SignalR Installera .NET-klientpaketet
Microsoft.AspNetCore.SignalR. Klientpaketet krävs för att .NET-klienter ska kunna ansluta till SignalR hubbar.
Installera klientbiblioteket genom att köra följande kommando i fönstret Package Manager Console :
Install-Package Microsoft.AspNetCore.SignalR.Client
Ansluta till en hubb
Skapa en anslutning genom att skapa en HubConnectionBuilder och anropa Build. Hubb-URL, protokoll, transporttyp, loggnivå, rubriker och andra alternativ kan konfigureras när du skapar en anslutning. Konfigurera alla nödvändiga alternativ genom att infoga någon av HubConnectionBuilder metoderna i Build. Starta anslutningen med 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);
}
}
}
}
Hantera förlorad anslutning
Återanslut automatiskt
HubConnection kan konfigureras för att automatiskt återansluta med hjälp av metoden WithAutomaticReconnect på HubConnectionBuilder. Den återansluts inte automatiskt som standard.
HubConnection connection= new HubConnectionBuilder()
.WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
.WithAutomaticReconnect()
.Build();
Utan några parametrar WithAutomaticReconnect() konfigurerar klienten att vänta 0, 2, 10 respektive 30 sekunder innan varje återanslutningsförsök provas och stoppas efter fyra misslyckade försök.
Innan du startar några återanslutningsförsök kommer HubConnection övergå till tillståndet HubConnectionState.Reconnecting och utlösa händelsen Reconnecting. Detta ger en möjlighet att varna användarna om att anslutningen har gått förlorad och att inaktivera gränssnittselement. Icke-interaktiva appar kan börja köa eller släppa meddelanden.
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;
};
Om klienten återansluter inom de första fyra försöken HubConnection övergår den tillbaka till Connected tillståndet och utlöser Reconnected händelsen. Detta ger en möjlighet att informera användarna om att anslutningen har återupprättats och att eventuella köade meddelanden raderas.
Eftersom anslutningen framstår som helt ny för servern, kommer en ny ConnectionId att ges till Reconnected händelsehanterarna.
Warning
Händelsehanterarens ReconnectedconnectionId parameter är null om den HubConnection har konfigurerats för att hoppa över förhandling.
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() kommer inte att konfigurera HubConnection för att försöka igen vid initiala startfel, så startfel måste hanteras manuellt:
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);
}
}
}
Om klienten inte återansluter inom de första fyra försöken HubConnection övergår den till Disconnected tillståndet och utlöser Closed händelsen. Detta ger möjlighet att försöka starta om anslutningen manuellt eller informera användarna om att anslutningen har förlorats permanent.
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;
};
För att konfigurera ett anpassat antal återanslutningsförsök innan du kopplar från eller ändrar återanslutningstidpunkten accepterar WithAutomaticReconnect en matris med tal som representerar fördröjningen i millisekunder att vänta innan varje återanslutningsförsök startas.
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.
I föregående exempel konfigureras HubConnection för att börja försöka återansluta omedelbart efter att anslutningen har gått förlorad. Detta gäller även för standardkonfigurationen.
Om det första återanslutningsförsöket misslyckas startar även det andra återanslutningsförsöket omedelbart i stället för att vänta 2 sekunder som i standardkonfigurationen.
Om det andra återanslutningsförsöket misslyckas startar det tredje återanslutningsförsöket om 10 sekunder, vilket återigen liknar standardkonfigurationen.
Det anpassade beteendet avviker sedan igen från standardbeteendet genom att stoppa efter det tredje återanslutningsförsöksfelet. I standardkonfigurationen skulle det finnas ytterligare ett återanslutningsförsök på ytterligare 30 sekunder.
Om du vill ha ännu mer kontroll över tidpunkten och antalet automatiska återanslutningsförsök WithAutomaticReconnect godkänner du ett objekt som implementerar IRetryPolicy gränssnittet, som har en enda metod med namnet NextRetryDelay.
NextRetryDelay tar ett argument med typen RetryContext.
RetryContext har tre egenskaper: PreviousRetryCount, ElapsedTime och RetryReason, som är en long, en TimeSpan och en Exception respektive. Före det första återanslutningsförsöket är båda PreviousRetryCount och ElapsedTime noll, och RetryReason kommer att vara undantaget som gjorde att anslutningen gick förlorad. Efter varje misslyckat återförsök PreviousRetryCount ökas med ett, ElapsedTime uppdateras för att återspegla den tid som lagts på att återansluta hittills, och RetryReason kommer att vara undantaget som orsakade att det senaste återanslutningsförsöket misslyckades.
NextRetryDelay måste returnera antingen ett TimeSpan som representerar tiden att vänta innan nästa återanslutningsförsök eller null om HubConnection ska sluta återansluta.
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();
Du kan också skriva kod som återansluter klienten manuellt, vilket visas i Återanslut manuellt.
Återanslut manuellt
Warning
Före 3.0 återansluter inte .NET-klienten för SignalR automatiskt. Du måste skriva kod som återansluter klienten manuellt.
Använd händelsen Closed för att svara på en förlorad anslutning. Du kanske till exempel vill automatisera återanslutningen.
Händelsen Closed kräver ett ombud som returnerar en Task, som gör att asynkron kod kan köras utan att använda async void. För att uppfylla ombudssignaturen i en Closed händelsehanterare som körs synkront returnerar du Task.CompletedTask:
connection.Closed += (error) => {
// Do your close logic.
return Task.CompletedTask;
};
Den främsta orsaken till asynkront stöd är att du kan starta om anslutningen. Att starta en anslutning är en asynkron åtgärd.
I en Closed hanterare som startar om anslutningen bör du överväga att vänta på en slumpmässig fördröjning för att förhindra överlagring av servern, som du ser i följande exempel:
connection.Closed += async (error) =>
{
await Task.Delay(new Random().Next(0,5) * 1000);
await connection.StartAsync();
};
Anropa hubbmetoder från klienten
InvokeAsync anropar metoder på hubben. Skicka hubbmetodens namn och de argument som definierats i hubbmetoden till InvokeAsync.
SignalR är asynkront, så använd async och await när du gör anropen.
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
Metoden InvokeAsync returnerar en Task som slutförs när servermetoden returneras. Returvärdet, om det finns något, anges som ett resultat av Task. Eventuella undantag som genereras av metoden på servern skapar en felaktig Task. Använd await syntax för att vänta tills servermetoden har slutförts och try...catch syntaxen för att hantera fel.
Metoden SendAsync returnerar en Task som slutförs när meddelandet har skickats till servern. Inget returvärde anges eftersom detta Task inte väntar tills servermetoden har slutförts. Eventuella undantag som kastas på klienten när meddelandet skickas leder till en felaktig Task. Använd await och try...catch syntax för att hantera sändningsfel.
Note
Anrop av hubbmetoder från en klient stöds endast när man använder Azure SignalR-tjänsten i standardläge för. Mer information finns i Vanliga frågor och svar.
Anropa klientmetoder från hubben
Definiera metoder som hubben anropar med efter connection.On att ha skapats, men innan anslutningen startas.
connection.On<string, string>("ReceiveMessage", (user, message) =>
{
this.Dispatcher.Invoke(() =>
{
var newMessage = $"{user}: {message}";
messagesList.Items.Add(newMessage);
});
});
Föregående kod i connection.On körs när kod på serversidan anropar den med hjälp av SendAsync -metoden.
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
Note
Även om hubbsidan i anslutningen stöder starkt skrivna meddelanden, måste klienten registrera sig med hjälp av den generiska metoden HubConnection.On med metodnamnet. För ett exempel, se SignalR.
Felhantering och loggning
Hantera fel med en try-catch-instruktion. Kontrollera objektet Exception för att fastställa vilken åtgärd som ska vidtas när ett fel inträffar.
try
{
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
}
catch (Exception ex)
{
messagesList.Items.Add(ex.Message);
}
Ytterligare resurser
ASP.NET Core