Delen via


Server probleemloos afsluiten

Microsoft Azure SignalR Service biedt twee modi voor het probleemloos afsluiten van een SignalR Hub-server wanneer Azure SignalR Service is geconfigureerd als standaardmodus die Azure SignalR Service fungeert als een proxy tussen de SignalR-clients en de SignalR Hub-server.

Het belangrijkste voordeel van het gebruik van deze functie is om te voorkomen dat uw klant onverwacht verbroken verbindingen ondervindt.

In plaats daarvan kunt u wachten op uw clientverbindingen om zichzelf te sluiten met betrekking tot uw bedrijfslogica of zelfs de clientverbinding naar een andere server migreren zonder gegevens te verliezen.

Hoe het werkt

Over het algemeen zijn er vier fasen in een probleemloos afsluitproces:

  1. De server offline instellen

    Dit betekent dat er geen clientverbindingen meer naar deze server worden gerouteerd.

  2. Triggerhaakjes OnShutdown

    U kunt afsluithook registreren voor elke hub waarvan u eigenaar bent op uw server. Ze worden aangeroepen met betrekking tot de geregistreerde bestelling direct nadat we een FINACK-antwoord van onze Azure SignalR-service hebben ontvangen. Dit betekent dat deze server offline is ingesteld in de Azure SignalR-service.

    U kunt berichten uitzenden of een aantal schoonmaaktaken uitvoeren in deze fase, zodra alle afsluithaken zijn uitgevoerd, gaan we verder met de volgende fase.

  3. Wacht totdat alle clientverbindingen zijn voltooid, afhankelijk van de modus die u kiest. Dit kan het volgende zijn:

    Modus ingesteld op WaitForClientsToClose

    Azure SignalR Service bevat bestaande clients.

    Mogelijk moet u een manier ontwerpen, zoals het uitzenden van een sluitend bericht naar alle clients en uw clients vervolgens laten beslissen wanneer u zichzelf wilt sluiten/opnieuw verbinding wilt maken.

    Lees ChatSample voor voorbeeldgebruik, dat we een 'exit'-bericht uitzenden om de client te activeren sluiten in afsluithook.

    Modus ingesteld op MigrateClients

    Azure SignalR Service probeert de clientverbinding op deze server om te leiden naar een andere geldige server.

    In dit scenario OnConnectedAsync OnDisconnectedAsync worden deze respectievelijk geactiveerd op de nieuwe server en de oude server met een IConnectionMigrationFeature set in de Context, die kan worden gebruikt om te bepalen of de clientverbinding is gemigreerd of gemigreerd. Deze functie kan handig zijn, met name voor stateful scenario's.

    De clientverbinding wordt onmiddellijk gemigreerd nadat het huidige bericht is bezorgd, wat betekent dat het volgende bericht naar de nieuwe server wordt doorgestuurd.

  4. Serververbindingen stoppen

    Nadat alle clientverbindingen zijn gesloten/gemigreerd of de time-out (standaard 30's) is overschreden,

    SignalR Server SDK gaat door met het afsluiten van dit stadium en sluit alle serververbindingen.

    Clientverbindingen worden nog steeds verwijderd als deze niet kunnen worden gesloten/gemigreerd. Er is bijvoorbeeld geen geschikte doelserver/huidig client-naar-server-bericht voltooid.

Voorbeeldcodes.

Voeg de volgende opties toe wanneer AddAzureSignalR:

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

configureren OnConnected en OnDisconnected tijdens het instellen van de respijtmodus voor afsluiten MigrateClientsop .

We hebben een 'I Verbinding maken ionMigrationFeature' geïntroduceerd om aan te geven of een verbinding is gemigreerd/uitgeschakeld.

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