Sunucu düzgün kapatma

Microsoft Azure SignalR Hizmeti, Azure SignalR Hizmeti SignalR İstemcileri ile SignalR Hub Sunucusu arasında ara sunucu işlevi gören Azure SignalR Hizmeti Varsayılan mod olarak yapılandırıldığında SignalR Hub sunucusunu düzgün bir şekilde kapatmak için iki mod sağlar.

Bu özelliği kullanmanın temel avantajı, müşterinizin beklenmedik şekilde bağlantı kesintisi yaşamasını önlemektir.

Bunun yerine, istemci bağlantılarınızın iş mantığınıza göre kendilerini kapatmasını bekleyebilir, hatta veri kaybetmeden istemci bağlantısını başka bir sunucuya geçirebilirsiniz.

Nasıl çalışır

Genel olarak, düzgün bir kapatma işleminde dört aşama olacaktır:

  1. Sunucuyu çevrimdışı ayarlama

    Başka bir istemci bağlantısının bu sunucuya yönlendirilmeyecek olması anlamına gelir.

  2. Tetikleyici OnShutdown kancaları

    Sunucunuza sahip olduğunuz her hub için kapatma kancalarını kaydedebilirsiniz. Bunlar, Azure SignalR Hizmeti'mizden FINACK yanıtı aldıktan hemen sonra kayıtlı siparişle ilgili olarak çağrılır ve bu da sunucunun Azure SignalR Hizmeti çevrimdışı olarak ayarlandığı anlamına gelir.

    Bu aşamada iletileri yayınlayabilir veya bazı temizleme işleri yapabilirsiniz. Tüm kapatma kancaları yürütüldükten sonra sonraki aşamaya geçeceğiz.

  3. Tüm istemci bağlantıları bitene kadar bekleyin, seçtiğiniz moda bağlı olarak şu olabilir:

    Modu WaitForClientsToClose olarak ayarlayın

    Azure SignalR Hizmeti mevcut istemcileri barındıracaktır.

    Kapatma iletisini tüm istemcilere yayınlamak gibi bir yol tasarlamanız ve ardından istemcilerinizin ne zaman kapanacaklarına/yeniden bağlanacaklarına karar vermelerine izin vermeniz gerekebilir.

    Kapatma kancasında istemci kapatma işlemini tetikleyen bir 'çıkış' iletisi yayımladığımız örnek kullanım için ChatSample'ı okuyun.

    Mode set to MigrateClients

    Azure SignalR Hizmeti bu sunucudaki istemci bağlantısını başka bir geçerli sunucuya yeniden yönlendirmeye çalışır.

    Bu senaryoda, OnConnectedAsync OnDisconnectedAsync istemci bağlantısının geçirilip geçirilmediğini belirlemek için kullanılabilecek yeni sunucuda ve eski sunucuda sırasıyla içinde bir IConnectionMigrationFeature kümeyle Contexttetiklenir. Bu özellik özellikle durum bilgisi olan senaryolar için yararlı olabilir.

    İstemci bağlantısı, geçerli ileti teslim edildikten hemen sonra geçirilecek ve bu da bir sonraki iletinin yeni sunucuya yönlendirileceği anlamına gelir.

  4. Sunucu bağlantılarını durdurma

    Tüm istemci bağlantıları kapatıldıktan/geçirildikten veya zaman aşımı (varsayılan olarak 30'lar) aşıldıktan sonra,

    SignalR Sunucu SDK'sı kapatma işlemine bu aşamaya devam eder ve tüm sunucu bağlantılarını kapatır.

    İstemci bağlantıları kapatılamadıysa/geçirilemediyse yine de bırakılır. Örneğin, uygun bir hedef sunucu / geçerli istemciden sunucuya iletisi tamamlanmamıştır.

Örnek kodlar.

şu durumlarda AddAzureSignalRaşağıdaki seçenekleri ekleyin:

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

OnDisconnected ve ayarlarını düzgün kapatma modu olarak MigrateClientsayarlarken yapılandırınOnConnected.

Bir bağlantının geçirilip geçirilmediğini göstermek için bir "I Bağlan ionMigrationFeature" kullanıma sunulmuştur.

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