Apagado correcto del servidor

Microsoft Azure SignalR Service ofrece dos modos para apagar correctamente un servidor concentrador de SignalR cuando Azure SignalR Service está configurado como Modo predeterminado, cuando Azure SignalR Service actúa como proxy entre los clientes de SignalR y el servidor concentrador de SignalR.

La principal ventaja de usar esta característica es evitarle caídas de conexión inesperadas al cliente.

En su lugar, puede esperar a que las conexiones del cliente se cierren según la lógica de negocios o migrar la conexión de cliente a otro servidor sin perder datos.

Cómo funciona

En general, el proceso de apagado correcto consta de cuatro fases:

  1. Establezca el servidor sin conexión.

    Significa que no se enrutarán más conexiones de cliente a este servidor.

  2. Desencadene los enlaces de OnShutdown.

    Podría registrar enlaces de apagado de cada centro de conectividad que posea en el servidor. Se llamará con respecto al pedido registrado justo después de obtener una respuesta FINACK de azure SignalR Service, lo que significa que este servidor se ha establecido sin conexión en Azure SignalR Service.

    Puede difundir mensajes o realizar algunos trabajos de limpieza en esta fase, una vez ejecutados todos los enlaces de apagado, procederemos a la siguiente fase.

  3. Espere hasta que finalicen todas las conexiones de cliente. Según el modo que elija:

    Modo establecido en WaitForClientsToClose

    Azure SignalR Service mantendrá los clientes existentes.

    Es posible que tenga que diseñar una manera, como difundir un mensaje de cierre a todos los clientes y, a continuación, permitir que los clientes decidan cuándo cerrar o volver a conectarse a sí mismos.

    Lea ChatSample para un ejemplo de uso donde se difunde un mensaje "de salida" para desencadenar el cierre del cliente en el enlace de apagado.

    Modo establecido en MigrateClients

    Azure SignalR Service intentará volver a enrutar la conexión de cliente de este servidor a otro servidor válido.

    En este escenario, OnConnectedAsync y OnDisconnectedAsync se desencadenarán en el nuevo servidor y en el servidor anterior respectivamente con un IConnectionMigrationFeature conjunto en Context, que se puede usar para identificar si la conexión de cliente se migraba o se migraba. Esta característica podría ser útil especialmente para escenarios con estado.

    La conexión del cliente se migrará inmediatamente después de que se haya entregado el mensaje actual, lo que significa que el siguiente mensaje se enrutará al nuevo servidor.

  4. Detenga las conexiones con el servidor.

    Una vez cerradas o migradas todas las conexiones de cliente, o si se supera el tiempo de espera (30 s de manera predeterminada),

    el SDK del servidor de SignalR continuará el apagado con esta fase y cerrará todas las conexiones del servidor.

    Se anularán las conexiones de cliente aunque no se realice el cierre o la migración. Por ejemplo, no hay un servidor de destino adecuado o no ha finalizado el mensaje de cliente a servidor actual.

Códigos de ejemplo

Agregue las siguientes opciones cuando 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");
    });
});

configure OnConnected y OnDisconnected al establecer el modo de apagado correcto en MigrateClients.

Hemos introducido una "I Conectar ionMigrationFeature" para indicar si se ha migrado o fuera una conexión.

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