Ordnungsgemäßes Herunterfahren von Servern
Microsoft Azure SignalR Service bietet zwei Modi zum ordnungsgemäßen Herunterfahren eines SignalR-Hubservers, wenn Azure SignalR Service als Standardmodus konfiguriert ist, Azure SignalR Service als Proxy zwischen den SignalR-Clients und dem SignalR-Hubserver fungiert.
Der Hauptvorteil der Verwendung dieses Features besteht darin, dass bei Ihrem Kunden keine unerwarteten Verbindungsausfälle auftreten.
Stattdessen können Sie in Ihrer Geschäftslogik darauf warten, dass Ihre Clientverbindungen selbstständig getrennt werden, oder Sie können die Clientverbindung sogar zu einem anderen Server migrieren, ohne Daten zu verlieren.
Funktionsweise
Im Allgemeinen erfolgt das ordnungsgemäße Herunterfahren in vier Phasen:
Versetzen des Servers in den Offlinemodus
Dadurch werden keine weiteren Clientverbindungen an diesen Server weitergeleitet.
Auslösen von
OnShutdown
-HooksSie können für jeden Hub in Ihrem Besitz auf dem Server Shutdown-Hooks registrieren. Sie werden in Bezug auf den registrierten Auftrag aufgerufen, nachdem wir eine FINACK-Antwort von unserem Azure SignalR-Dienst erhalten haben, was bedeutet, dass dieser Server offline im Azure SignalR-Dienst festgelegt wurde.
Sie können Nachrichten übertragen oder einige sauber Ing-Aufträge in dieser Phase ausführen, sobald alle Herunterfahren-Hooks ausgeführt wurden, werden wir mit der nächsten Phase fortfahren.
Warten auf das Trennen aller Clientverbindungen. Dies ist vom ausgewählten Modus abhängig, der einer der folgenden sein kann:
Modus WaitForClientsToClose
Azure SignalR Service wartet auf vorhandene Clients.
Möglicherweise müssen Sie eine Möglichkeit entwerfen, z. B. eine Abschlussnachricht an alle Clients übertragen, und lassen Sie Ihre Clients entscheiden, wann sie sich selbst schließen/erneut verbinden möchten.
Sehen Sie sich das ChatSample an. Dort finden Sie ein Beispiel, bei dem über einen Shutdown-Hook eine „exit“-Meldung übertragen wird, um die Clients zu trennen.
Modus MigrateClients
Azure SignalR Service versucht, die Clientverbindungen auf diesem Server auf einen anderen gültigen Server umzuleiten.
In diesem Szenario und wird auf dem neuen Server bzw. dem alten Server mit einem
IConnectionMigrationFeature
Satz imContext
Bereich ausgelöst, der verwendet werden kann, um zu ermitteln,OnConnectedAsync
OnDisconnectedAsync
ob die Clientverbindung migriert oder migriert wurde. Dieses Feature kann besonders für zustandsbehaftete Szenarien nützlich sein.Die Clientverbindung wird sofort migriert, nachdem die aktuelle Nachricht übermittelt wurde. Dies bedeutet, dass die nächste Nachricht an den neuen Server weitergeleitet wird.
Trennen der Serververbindungen
Nachdem alle Clientverbindungen getrennt/migriert wurden oder das Timeout (standardmäßig 30 s) überschritten wurde, geschieht Folgendes:
Das SignalR-Server SDK fährt mit dieser Phase des Herunterfahrens fort und schließt alle Serververbindungen.
Clientverbindungen, die nicht geschlossen oder migriert wurden, werden trotzdem getrennt. Beispiele sind das Fehlen eines geeigneten Zielservers oder eine nicht abgeschlossene Meldung vom aktuellen Client zum Server.
Codebeispiele
Fügen Sie bei Verwendung von AddAzureSignalR
folgende Optionen hinzu:
services.AddSignalR().AddAzureSignalR(option =>
{
option.GracefulShutdown.Mode = GracefulShutdownMode.WaitForClientsClose;
// option.GracefulShutdown.Mode = GracefulShutdownMode.MigrateClients;
option.GracefulShutdown.Timeout = TimeSpan.FromSeconds(30);
option.GracefulShutdown.Add<Chat>(async (c) =>
{
await c.Clients.All.SendAsync("exit");
});
});
Konfigurieren von OnConnected
und OnDisconnected
beim Herunterfahrmodus MigrateClients
Wir haben ein "I Verbinden ionMigrationFeature" eingeführt, um anzugeben, ob eine Verbindung migriert/out wurde.
public class Chat : Hub {
public override async Task OnConnectedAsync()
{
Console.WriteLine($"{Context.ConnectionId} connected.");
var feature = Context.Features.Get<IConnectionMigrationFeature>();
if (feature != null)
{
Console.WriteLine($"[{feature.MigrateTo}] {Context.ConnectionId} is migrated from {feature.MigrateFrom}.");
// Your business logic.
}
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception e)
{
Console.WriteLine($"{Context.ConnectionId} disconnected.");
var feature = Context.Features.Get<IConnectionMigrationFeature>();
if (feature != null)
{
Console.WriteLine($"[{feature.MigrateFrom}] {Context.ConnectionId} will be migrated to {feature.MigrateTo}.");
// Your business logic.
}
await base.OnDisconnectedAsync(e);
}
}