Arrêt approprié du serveur

Microsoft Azure SignalR Service fournit deux modes d’arrêt normal d’un serveur de hubs SignalR quand Azure SignalR Service est configuré en mode par défaut, Azure SignalR Service agissant comme proxy entre les clients SignalR et le serveur de hubs SignalR.

L’utilisation de cette fonctionnalité présente un avantage clé : éviter à votre client de subir des pertes de connexion inattendues.

À la place, vous pouvez soit attendre la fermeture de vos connexions clientes en fonction de votre logique métier, soit migrer la connexion cliente vers un autre serveur sans perdre de données.

Fonctionnement

En général, il existe quatre étapes dans un processus d’arrêt approprié :

  1. Mettre le serveur hors connexion

    Cela signifie qu’aucune autre connexion cliente n’est routée vers ce serveur.

  2. Déclencher des crochets OnShutdown

    Vous pouvez inscrire des crochets d’arrêt pour chaque hub que vous avez sur votre serveur. Ils seront appelés par rapport à l’ordre inscrit juste après avoir obtenu une réponse FINACK de notre service Azure SignalR, ce qui signifie que ce serveur a été défini hors connexion dans Azure SignalR Service.

    Vous pouvez diffuser des messages ou effectuer des tâches de propre dans cette phase, une fois que tous les hooks d’arrêt ont été exécutés, nous allons passer à la phase suivante.

  3. Attendre la fin de toutes les connexions clientes. Selon le mode que vous choisissez, il peut s’agir de :

    Mode ayant la valeur WaitForClientsToClose

    Azure SignalR Service contient les clients existants.

    Vous devrez peut-être concevoir un moyen, comme diffuser un message de fermeture à tous les clients, puis laisser vos clients décider quand fermer/se reconnecter.

    Lisez ChatSample pour accéder à des exemples d’utilisation qui montrent comment nous diffusons un message de « sortie » afin de déclencher la fermeture du client dans le crochet d’arrêt.

    Mode ayant la valeur MigrateClients

    Azure SignalR Service tente de rerouter la connexion cliente du serveur vers un autre serveur valide.

    Dans ce scénario, OnConnectedAsync et OnDisconnectedAsync sera déclenché sur le nouveau serveur et l’ancien serveur respectivement avec un IConnectionMigrationFeature ensemble dans le Context, qui peut être utilisé pour identifier si la connexion cliente a été migrée ou migrée. Cette fonctionnalité peut être utile en particulier pour les scénarios avec état.

    La connexion cliente est immédiatement migrée après la remise du message actuel, ce qui signifie que le message suivant est routé vers le nouveau serveur.

  4. Arrêter les connexions au serveur

    Une fois que toutes les connexions clientes ont été fermées/migrées, ou que le délai d’expiration (30 s par défaut) est dépassé,

    Le kit SDK SignalR Server poursuit le processus d’arrêt jusqu’à cette phase, puis ferme toutes les connexions au serveur.

    Les connexions clientes sont quand même supprimées, si elles n’ont pas pu être fermées/migrées. Par exemple, il n’existe aucun serveur cible approprié, ou le message du client au serveur est incomplet.

Exemples de code.

Ajoutez les options suivantes avec 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");
    });
});

Configurez OnConnected et OnDisconnected tout en définissant un mode d’arrêt approprié pour MigrateClients.

Nous avons introduit une « I Connecter ionMigrationFeature » pour indiquer si une connexion a été migrée/sortante.

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