Desligamento gracioso do servidor
O Serviço SignalR do Microsoft Azure fornece dois modos para desligar normalmente um servidor SignalR Hub quando o Serviço Azure SignalR é configurado como modo Padrão em que o Serviço Azure SignalR atua como um proxy entre os Clientes SignalR e o Servidor SignalR Hub.
A principal vantagem de usar esse recurso é evitar que seu cliente sofra quedas inesperadas de conexão.
Em vez disso, você pode esperar que as conexões do cliente se fechem em relação à sua lógica de negócios ou até mesmo migrar a conexão do cliente para outro servidor sem perder dados.
Como funciona
Em geral, haverá quatro etapas em um processo de desligamento gracioso:
Definir o servidor offline
Isso significa que não haverá mais conexões de cliente roteadas para este servidor.
Ganchos de gatilho
OnShutdown
Você pode registrar ganchos de desligamento para cada hub que você possui em seu servidor. Eles serão chamados em relação ao pedido registrado logo após recebermos uma resposta FINACK do nosso Serviço Azure SignalR, o que significa que esse servidor foi definido offline no Serviço Azure SignalR.
Você pode transmitir mensagens ou fazer alguns trabalhos de limpeza nesta etapa, uma vez que todos os ganchos de desligamento tenham sido executados, passaremos para a próxima etapa.
Aguarde até que todas as conexões do cliente terminem, depende do modo que você escolher, pode ser:
Modo definido como WaitForClientsToClose
O Serviço Azure SignalR manterá clientes existentes.
Você pode ter que projetar uma maneira, como transmitir uma mensagem de fechamento para todos os clientes e, em seguida, deixar que seus clientes decidam quando fechar/se reconectar.
Leia o ChatSample para obter exemplos de uso, que transmitimos uma mensagem de 'saída' para acionar o fechamento do cliente no gancho de desligamento.
Modo definido como MigrateClients
O Serviço Azure SignalR tentará redirecionar a conexão do cliente neste servidor para outro servidor válido.
Nesse cenário, e será acionado no novo servidor e
OnDisconnectedAsync
no servidor antigo, respectivamente, com umIConnectionMigrationFeature
conjunto noContext
,OnConnectedAsync
que pode ser usado para identificar se a conexão do cliente estava sendo migrada para dentro ou para fora. Esse recurso pode ser útil especialmente para cenários com monitoração de estado.A conexão do cliente será migrada imediatamente após a mensagem atual ter sido entregue, o que significa que a próxima mensagem será roteada para o novo servidor.
Parar conexões de servidor
Depois que todas as conexões do cliente tiverem sido fechadas/migradas ou o tempo limite (30s por padrão) for excedido,
O SDK do SignalR Server prosseguirá o processo de desligamento para este estágio e fechará todas as conexões do servidor.
As conexões de cliente ainda serão descartadas se não conseguirem ser fechadas/migradas. Por exemplo, nenhuma mensagem de servidor de destino / cliente para servidor atual não foi concluída.
Códigos de exemplo.
Adicione as seguintes opções quando 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
e OnDisconnected
ao definir o modo de desligamento normal como MigrateClients
.
Introduzimos um "IConnectionMigrationFeature" para indicar se uma conexão estava sendo migrada para dentro/para fora.
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);
}
}