ASP.NET Core BlazorSignalR kılavuzu

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Önemli

Bu bilgiler, ticari olarak piyasaya sürülmeden önce önemli ölçüde değiştirilebilen bir yayın öncesi ürünle ilgilidir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.

Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Bu makalede, uygulamalarda bağlantıların Blazor nasıl yapılandırılıp yönetileceğini SignalR açıklanmaktadır.

ASP.NET Core SignalR yapılandırmasıyla ilgili genel yönergeler için, belgenin ASP.NET Core'aSignalRgenel bakış alanında, özellikle de ASP.NET Core SignalR yapılandırmasındaki konulara bakın.

Sunucu tarafı uygulamalar tarayıcıyla iletişim kurmak için ASP.NET Core SignalR kullanır. SignalR'nin barındırma ve ölçeklendirme koşulları sunucu tarafı uygulamaları için geçerlidir.

Blazordaha düşük gecikme süresi, güvenilirlik ve güvenlik nedeniyle aktarım olarak SignalR WebSockets kullanırken en iyi sonucu verir. Uzun Yoklama, WebSockets kullanılamadığında veya uygulama Uzun Yoklama kullanacak şekilde açıkça yapılandırıldığında tarafından SignalR kullanılır.

Durum bilgisi olan yeniden bağlantı ile Azure SignalR Hizmeti

Durum bilgisi olan yeniden bağlantı (WithStatefulReconnect), .NET 8 ile yayımlandı ancak şu anda Azure SignalR Hizmeti için desteklenmiyor. Daha fazla bilgi için bkz . Durum Bilgisi Olan Yeniden Bağlanma Desteği? (Azure/azure-signalr #1878).

Etkileşimli Sunucu bileşenleri için WebSocket sıkıştırması

Varsayılan olarak, Etkileşimli Sunucu bileşenleri:

CSP'yi frame-ancestors merkezi bir şekilde yapılandırmak isteyebileceğiniz için nullCSP değeri ConfigureWebSocketOptions olarak ayarlanarak el ile kaldırılabilir. frame-ancestors CSP merkezi bir şekilde yönetildiğinde, ilk belge her işlendiğinde ilkenin uygulanmasına dikkat edilmelidir. Uygulamayı saldırılara açık hale getirebileceğinden ilkenin tamamen kaldırılması önerilmez.

Kullanım örnekleri:

ayarını ConfigureWebSocketOptions yaparak sıkıştırmayı nulldevre dışı bırakın. Bu, uygulamanın saldırı güvenlik açığını azaltır ancak performansın düşmesine neden olabilir:

builder.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode(o => o.ConfigureWebSocketOptions = null)

Sıkıştırma etkinleştirildiğinde, WebSocket sıkıştırmasına 'none' izin veren ancak tarayıcıların uygulamayı herhangi <iframe>bir içine eklemesini engelleyen (tek tırnak gereklidir) değeriyle daha frame-ancestors katı bir CSP yapılandırın:

builder.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode(o => o.ContentSecurityFrameAncestorsPolicy = "'none'")

Sıkıştırma etkinleştirildiğinde, olarak ayarlayarak ContentSecurityFrameAncestorsPolicy CSP'yi nullkaldırınframe-ancestors. Bu senaryo yalnızca CSP'yi merkezi bir şekilde ayarlayan uygulamalar için önerilir:

builder.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode(o => o.ContentSecurityFrameAncestorsPolicy = null)

Önemli

Tarayıcılar, en katı ilke yönergesi değerini kullanarak birden çok CSP üst bilgisinden CSP yönergeleri uygular. Bu nedenle, bir geliştirici bilerek veya yanlışlıkla daha 'self' zayıf frame-ancestors bir ilke ekleyemez.

öğesine geçirilen ContentSecurityFrameAncestorsPolicydize değerinde tek tırnak işareti gerekir:

Desteklenmeyen değerler:none, self

'none','self'

Ek seçenekler arasında bir veya daha fazla konak kaynağı ve düzen kaynağı belirtme yer alır.

Güvenlik üzerindeki etkileri için bkz . ASP.NET Core Blazor etkileşimli sunucu tarafı işleme için tehdit azaltma kılavuzu. Yönerge hakkında frame-ancestors daha fazla bilgi için bkz . CSP: frame-ancestors (MDN belgeleri).

Çalışırken Yeniden Yükleme için yanıt sıkıştırmayı devre dışı bırakma

Çalışırken Yeniden Yükleme kullanırken ortamda Yanıt Sıkıştırma Ara Yazılımını Development devre dışı bırakın. Proje şablonundaki varsayılan kodun kullanılıp kullanılmadığı, her zaman istek işleme işlem hattında ilk olarak çağrısı UseResponseCompression yapın.

Program dosyasında:

if (!app.Environment.IsDevelopment())
{
    app.UseResponseCompression();
}

Kimlik doğrulaması için istemci tarafı SignalR çıkış noktaları arası anlaşma

Bu bölümde, 'nin temel istemcisini s veya HTTP kimlik doğrulaması üst bilgileri gibi kimlik bilgilerini gönderecek şekilde cookieyapılandırma SignalRaçıklanmaktadır.

Çıkış noktaları fetch arası isteklerde ayarlamak Include için kullanınSetBrowserRequestCredentials.

IncludeRequestCredentialsMessageHandler.cs:

using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.WebAssembly.Http;

public class IncludeRequestCredentialsMessageHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);
        return base.SendAsync(request, cancellationToken);
    }
}

Hub bağlantısının derlendiği yere şu seçeneği atayın HttpMessageHandlerHttpMessageHandlerFactory :

private HubConnectionBuilder? hubConnection;

...

hubConnection = new HubConnectionBuilder()
    .WithUrl(new Uri(Navigation.ToAbsoluteUri("/chathub")), options =>
    {
        options.HttpMessageHandlerFactory = innerHandler => 
            new IncludeRequestCredentialsMessageHandler { InnerHandler = innerHandler };
    }).Build();

Yukarıdaki örnek, konumundaki mutlak URI adresine merkez bağlantı URL'sini /chathubyapılandırıyor. URI, örneğin https://signalr.example.combir dize aracılığıyla veya yapılandırma yoluyla da ayarlanabilir. Navigation eklenen NavigationManagerbir ...

Daha fazla bilgi için bkz . ASP.NET Core SignalR yapılandırması.

İstemci tarafı işleme

Prerendering yapılandırılırsa, sunucuya istemci bağlantısı kurulmadan önce ön kayıt gerçekleşir. Daha fazla bilgi için bkz . Prerender ASP.NET Core Razor bileşenleri.

Prerendering yapılandırılırsa, sunucuya istemci bağlantısı kurulmadan önce ön kayıt gerçekleşir. Daha fazla bilgi için aşağıdaki makaleleri inceleyin:

Önceden oluşturulmuş durum boyutu ve SignalR ileti boyutu sınırı

Önceden girilmiş büyük bir durum boyutu devre iletisi boyutu sınırını aşabilir SignalR ve bu da aşağıdaki sonuçlara neden olur:

  • Bağlantı SignalR hattı istemcide bir hatayla başlatılamıyor: Circuit host not initialized.
  • bağlantı hattı başarısız olduğunda istemcideki yeniden bağlantı iletişim kutusu görüntülenir. Kurtarma mümkün değildir.

Sorunu çözmek için aşağıdaki yaklaşımlardan birini kullanın:

  • Önceden yenilenen duruma yerleştirdiğiniz veri miktarını azaltın.
  • SignalR İleti boyutu sınırını artırın. UYARI: Sınırın artırılması Hizmet Reddi (DoS) saldırı riskini artırabilir.

Ek istemci tarafı kaynakları

Sunucu tarafı webfarm barındırma için yapışkan oturumları kullanma

Uygulama Blazor , sunucuda kullanıcı arabirimi durumu oluşturan ilk istemci isteğine yanıt olarak hazırlar. İstemci bir SignalR bağlantı oluşturmaya çalıştığında, istemcinin aynı sunucuya yeniden bağlanması gerekir. Birden fazla arka uç sunucusu kullanımda olduğunda, uygulamanın bağlantılar için SignalR yapışkan oturumlar uygulaması gerekir.

Not

Aşağıdaki hata, webfarm'da yapışkan oturumları etkinleştirmemiş bir uygulama tarafından oluşturulur:

blazor.server.js:1 Yakalanmadı (söz verilen) Hata: Temel alınan bağlantı kapatıldığı için çağrı iptal edildi.

Sunucu tarafı Azure SignalR Hizmeti

Microsoft Azure'da SignalR barındırılan sunucu tarafı geliştirme için Azure Hizmeti'ni kullanmanızı öneririz. Hizmet, bir sunucu tarafı uygulamasını Blazor çok sayıda eşzamanlı SignalR bağlantıya ölçeklendirmek için uygulamanın Hub'ı ile birlikte çalışır. Buna ek olarak, SignalR Hizmetin küresel erişim ve yüksek performanslı veri merkezleri coğrafya nedeniyle gecikme süresini azaltmaya önemli ölçüde yardımcı olur.

Yapışkan oturumlar, hizmetin seçeneği veya yapılandırma değeri Requiredolarak ayarlanarak Azure SignalR Hizmeti ServerStickyMode için etkinleştirilir. Daha fazla bilgi için bkz . ASP.NET Core sunucu tarafı Blazor uygulamaları barındırma ve dağıtma.

Sunucu tarafı bağlantı hattı işleyici seçenekleri

bağlantı hattını ile CircuitOptionsyapılandırın. Başvuru kaynağındaki varsayılan değerleri görüntüleyin.

Not

.NET başvuru kaynağına yönelik belge bağlantıları genellikle deponun varsayılan dalını yükler ve bu dal .NET'in sonraki sürümü için geçerli geliştirmeyi temsil eder. Belirli bir sürümün etiketini seçmek için Dalları veya etiketleri değiştir açılan listesini kullanın. Daha fazla bilgi için bkz. ASP.NET Core kaynak kodunun sürüm etiketini seçme (dotnet/AspNetCore.Docs #26205).

dosyadaki Program seçenekleri, için temsilci olarak bir AddInteractiveServerComponentsseçenekle okuyun veya ayarlayın. Yer {OPTION} tutucu seçeneği {VALUE} , yer tutucu ise değerdir.

Program dosyasında:

builder.Services.AddRazorComponents().AddInteractiveServerComponents(options =>
{
    options.{OPTION} = {VALUE};
});

dosyadaki Program seçenekleri, için temsilci olarak bir AddServerSideBlazorseçenekle okuyun veya ayarlayın. Yer {OPTION} tutucu seçeneği {VALUE} , yer tutucu ise değerdir.

Program dosyasında:

builder.Services.AddServerSideBlazor(options =>
{
    options.{OPTION} = {VALUE};
});

seçeneğinin Startup.ConfigureServices temsilcisi AddServerSideBlazorolan seçeneklerle içindeki seçenekleri okuyun veya ayarlayın. Yer {OPTION} tutucu seçeneği {VALUE} , yer tutucu ise değerdir.

Startup.csiçindeStartup.ConfigureServices:

services.AddServerSideBlazor(options =>
{
    options.{OPTION} = {VALUE};
});

öğesini yapılandırmak HubConnectionContextiçin ile kullanın HubConnectionContextOptionsAddHubOptions. Başvuru kaynağında hub bağlantısı bağlam seçeneklerinin varsayılanlarını görüntüleyin. Belgelerdeki SignalR seçenek açıklamaları için bkz . ASP.NET Çekirdek SignalR yapılandırması. Yer {OPTION} tutucu seçeneği {VALUE} , yer tutucu ise değerdir.

Not

.NET başvuru kaynağına yönelik belge bağlantıları genellikle deponun varsayılan dalını yükler ve bu dal .NET'in sonraki sürümü için geçerli geliştirmeyi temsil eder. Belirli bir sürümün etiketini seçmek için Dalları veya etiketleri değiştir açılan listesini kullanın. Daha fazla bilgi için bkz. ASP.NET Core kaynak kodunun sürüm etiketini seçme (dotnet/AspNetCore.Docs #26205).

Program dosyasında:

builder.Services.AddRazorComponents().AddInteractiveServerComponents().AddHubOptions(options =>
{
    options.{OPTION} = {VALUE};
});

Program dosyasında:

builder.Services.AddServerSideBlazor().AddHubOptions(options =>
{
    options.{OPTION} = {VALUE};
});

Startup.csiçindeStartup.ConfigureServices:

services.AddServerSideBlazor().AddHubOptions(options =>
{
    options.{OPTION} = {VALUE};
});

Uyarı

varsayılan değeri MaximumReceiveMessageSize 32 KB'tır. Değerin artırılması Hizmet Reddi (DoS) saldırıları riskini artırabilir.

Bellek yönetimi hakkında bilgi için bkz . ASP.NET Core sunucu tarafı Blazor uygulamaları barındırma ve dağıtma.

Blazor hub seçenekleri

Hub'ı denetlemek HttpConnectionDispatcherOptionsBlazor için seçenekleri yapılandırınMapBlazorHub. Başvuru kaynağında hub bağlantı dağıtıcısı seçeneklerinin varsayılanlarını görüntüleyin. Yer {OPTION} tutucu seçeneği {VALUE} , yer tutucu ise değerdir.

Not

.NET başvuru kaynağına yönelik belge bağlantıları genellikle deponun varsayılan dalını yükler ve bu dal .NET'in sonraki sürümü için geçerli geliştirmeyi temsil eder. Belirli bir sürümün etiketini seçmek için Dalları veya etiketleri değiştir açılan listesini kullanın. Daha fazla bilgi için bkz. ASP.NET Core kaynak kodunun sürüm etiketini seçme (dotnet/AspNetCore.Docs #26205).

Çağrısının app.MapBlazorHub ardından uygulamanın Program dosyasına şu çağrıyı app.MapRazorComponents yerleştirin:

app.MapBlazorHub(options =>
{
    options.{OPTION} = {VALUE};
});

app.MapBlazorHub Uygulamanın Program dosyasında seçeneklerini belirtin:

app.MapBlazorHub(options =>
{
    options.{OPTION} = {VALUE};
});

Uç nokta yönlendirme yapılandırmasında seçeneklerini app.MapBlazorHub belirtin:

app.UseEndpoints(endpoints =>
{
    endpoints.MapBlazorHub(options =>
    {
        options.{OPTION} = {VALUE};
    });
    ...
});

Maksimum alma iletisi boyutu

Bu bölüm yalnızca uygulayan SignalRprojeler için geçerlidir.

Hub yöntemleri için izin verilen en büyük gelen SignalR ileti boyutu , (varsayılan: 32 KB) ile HubOptions.MaximumReceiveMessageSize sınırlıdır. SignalR hatadan daha MaximumReceiveMessageSize büyük iletiler. Çerçeve, hub'dan istemciye ileti SignalR boyutuna bir sınır getirmez.

Günlük kaydı Hata Ayıklama veya İzleme olarak ayarlı olmadığındaSignalR, ileti boyutu hatası yalnızca tarayıcının geliştirici araçları konsolunda görüntülenir:

Hata: Bağlan bağlantısı 'Hata: Sunucu kapatma sırasında bir hata döndürdü: Bağlan ion bir hatayla kapatıldı.' hatasıyla kesildi.

SignalR Sunucu tarafı günlüğü Hata Ayıklama veya İzleme olarak ayarlandığında, sunucu tarafı günlük kaydı ileti boyutu hatası için bir InvalidDataException görünür.

appsettings.Development.json:

{
  "DetailedErrors": true,
  "Logging": {
    "LogLevel": {
      ...
      "Microsoft.AspNetCore.SignalR": "Debug"
    }
  }
}

Hata:

System.IO.InvalidDataException: En fazla 32768B ileti boyutu aşıldı. İleti boyutu AddHubOptions'da yapılandırılabilir.

Bir yaklaşım, dosyada ayarlanarak MaximumReceiveMessageSize sınırın artırılmasını Program içerir. Aşağıdaki örnek, maksimum alma iletisi boyutunu 64 KB olarak ayarlar:

builder.Services.AddRazorComponents().AddInteractiveServerComponents()
    .AddHubOptions(options => options.MaximumReceiveMessageSize = 64 * 1024);

SignalR Gelen ileti boyutu sınırının artırılması, daha fazla sunucu kaynağı gerektirme maliyetine neden olur ve Hizmet Reddi (DoS) saldırıları riskini artırır. Buna ek olarak, bellekte dize veya bayt dizileri olarak büyük miktarda içerik okumak da çöp toplayıcı ile kötü çalışan ayırmalara neden olabilir ve bu da ek performans cezalarına neden olabilir.

Büyük yükleri okumak için daha iyi bir seçenek, içeriği daha küçük parçalar halinde göndermek ve yükü olarak Streamişlemektir. Bu, büyük JavaScript (JS) birlikte çalışma JSON yükleri okunurken veya birlikte çalışma verileri ham bayt olarak kullanılabiliyorsa JS kullanılabilir. Sunucu tarafı uygulamalarda bileşene benzer teknikler kullanan büyük ikili yüklerin gönderilmesini InputFile gösteren bir örnek için bkz. İkili Gönderme örnek uygulaması veInputLargeTextAreaBlazorBileşen Örneği.

Not

.NET başvuru kaynağına yönelik belge bağlantıları genellikle deponun varsayılan dalını yükler ve bu dal .NET'in sonraki sürümü için geçerli geliştirmeyi temsil eder. Belirli bir sürümün etiketini seçmek için Dalları veya etiketleri değiştir açılan listesini kullanın. Daha fazla bilgi için bkz. ASP.NET Core kaynak kodunun sürüm etiketini seçme (dotnet/AspNetCore.Docs #26205).

Üzerinde SignalR büyük yükleri işleyen formlar doğrudan akış birlikte çalışma JS özelliğini de kullanabilir. Daha fazla bilgi için bkz . ASP.NET Core'da BlazorJavaScript işlevlerinden .NET yöntemlerini çağırma. Verileri sunucuya aktaran <textarea> bir form örneği için bkz . ASP.NET Core Blazor formlarında sorun giderme.

Bir yaklaşım, dosyada ayarlanarak MaximumReceiveMessageSize sınırın artırılmasını Program içerir. Aşağıdaki örnek, maksimum alma iletisi boyutunu 64 KB olarak ayarlar:

builder.Services.AddServerSideBlazor()
    .AddHubOptions(options => options.MaximumReceiveMessageSize = 64 * 1024);

SignalR Gelen ileti boyutu sınırının artırılması, daha fazla sunucu kaynağı gerektirme maliyetine neden olur ve Hizmet Reddi (DoS) saldırıları riskini artırır. Buna ek olarak, bellekte dize veya bayt dizileri olarak büyük miktarda içerik okumak da çöp toplayıcı ile kötü çalışan ayırmalara neden olabilir ve bu da ek performans cezalarına neden olabilir.

Büyük yükleri okumak için daha iyi bir seçenek, içeriği daha küçük parçalar halinde göndermek ve yükü olarak Streamişlemektir. Bu, büyük JavaScript (JS) birlikte çalışma JSON yükleri okunurken veya birlikte çalışma verileri ham bayt olarak kullanılabiliyorsa JS kullanılabilir. bileşenine benzer teknikleri kullanan büyük Blazor Server ikili yüklerin gönderilmesiniInputFilegösteren bir örnek için bkz. İkili Gönderme örnek uygulaması veBlazorInputLargeTextArea Bileşen Örneği.

Not

.NET başvuru kaynağına yönelik belge bağlantıları genellikle deponun varsayılan dalını yükler ve bu dal .NET'in sonraki sürümü için geçerli geliştirmeyi temsil eder. Belirli bir sürümün etiketini seçmek için Dalları veya etiketleri değiştir açılan listesini kullanın. Daha fazla bilgi için bkz. ASP.NET Core kaynak kodunun sürüm etiketini seçme (dotnet/AspNetCore.Docs #26205).

Üzerinde SignalR büyük yükleri işleyen formlar doğrudan akış birlikte çalışma JS özelliğini de kullanabilir. Daha fazla bilgi için bkz . ASP.NET Core'da BlazorJavaScript işlevlerinden .NET yöntemlerini çağırma. Bir uygulamadaki verilerin akışını <textarea> sağlayan bir Blazor Server form örneği için bkz . ASP.NET Core Blazor formlarında sorun giderme.

içinde Startup.ConfigureServicesayarlayarak MaximumReceiveMessageSize sınırı artırın:

services.AddServerSideBlazor()
    .AddHubOptions(options => options.MaximumReceiveMessageSize = 64 * 1024);

SignalR Gelen ileti boyutu sınırının artırılması, daha fazla sunucu kaynağı gerektirme maliyetine neden olur ve Hizmet Reddi (DoS) saldırıları riskini artırır. Buna ek olarak, bellekte dize veya bayt dizileri olarak büyük miktarda içerik okumak da çöp toplayıcı ile kötü çalışan ayırmalara neden olabilir ve bu da ek performans cezalarına neden olabilir.

Büyük miktarda veri aktaran kod geliştirirken aşağıdaki yönergeleri göz önünde bulundurun:

  • Verileri daha küçük parçalara ayırın ve tüm veriler sunucu tarafından alınana kadar veri kesimlerini sıralı olarak gönderin.
  • ve C# kodunda JS büyük nesneler ayırmayın.
  • Veri gönderirken veya alırken ana kullanıcı arabirimi iş parçacığını uzun süreler boyunca engellemeyin.
  • İşlem tamamlandığında veya iptal edildiğinde boş tüketilen bellek.
  • Güvenlik amacıyla aşağıdaki ek gereksinimleri zorunlu kılın:
    • Geçirilebilen en büyük dosya veya veri boyutunu bildirin.
    • İstemciden sunucuya en düşük karşıya yükleme oranını bildirin.
  • Veriler sunucu tarafından alındıktan sonra şu şekilde olabilir:
    • Tüm kesimler toplanana kadar geçici olarak bellek arabelleğinde depolanır.
    • Hemen tüketilir. Örneğin, veriler hemen bir veritabanında depolanabilir veya her kesim alınırken diske yazılabilir.

Blazor sunucu tarafı Hub uç noktası yol yapılandırması

Program dosyasında, öğesini uygulamanın varsayılan yoluna eşlemek BlazorHub için öğesini çağırınMapBlazorHub. Betik Blazor (blazor.*.js) tarafından MapBlazorHuboluşturulan uç noktayı otomatik olarak gösterir.

Kullanıcı arabiriminde sunucu tarafı bağlantı durumunu Düşünceler

İstemci bağlantının kaybolduğunu algıladığında, istemci yeniden bağlanmayı denerken kullanıcıya varsayılan bir kullanıcı arabirimi görüntülenir. Yeniden bağlantı başarısız olursa, kullanıcıya yeniden deneme seçeneği sağlanır.

Kullanıcı arabirimini özelleştirmek için ile tek bir idcomponents-reconnect-modalöğe tanımlayın. Aşağıdaki örnek, öğesini bileşene App yerleştirir.

App.razor:

Kullanıcı arabirimini özelleştirmek için ile tek bir idcomponents-reconnect-modalöğe tanımlayın. Aşağıdaki örnek, öğesini konak sayfasına yerleştirir.

Pages/_Host.cshtml:

Kullanıcı arabirimini özelleştirmek için ile tek bir idcomponents-reconnect-modalöğe tanımlayın. Aşağıdaki örnek, öğesini düzen sayfasına yerleştirir.

Pages/_Layout.cshtml:

Kullanıcı arabirimini özelleştirmek için ile tek bir idcomponents-reconnect-modalöğe tanımlayın. Aşağıdaki örnek, öğesini konak sayfasına yerleştirir.

Pages/_Host.cshtml:

<div id="components-reconnect-modal">
    There was a problem with the connection!
</div>

Not

bir idcomponents-reconnect-modal içeren birden fazla öğe uygulama tarafından işlenirse, yalnızca ilk işlenen öğe öğeyi görüntülemek veya gizlemek için CSS sınıf değişikliklerini alır.

Sitenin stil sayfasına aşağıdaki CSS stillerini ekleyin.

wwwroot/app.css:

wwwroot/css/site.css:

#components-reconnect-modal {
    display: none;
}

#components-reconnect-modal.components-reconnect-show, 
#components-reconnect-modal.components-reconnect-failed, 
#components-reconnect-modal.components-reconnect-rejected {
    display: block;
}

Aşağıdaki tabloda, framework tarafından Blazor öğesine uygulanan components-reconnect-modal CSS sınıfları açıklanmaktadır.

CSS sınıfı Gösterir...
components-reconnect-show Bağlantı kesildi. İstemci yeniden bağlanmaya çalışır. Kalıcıyı gösterin.
components-reconnect-hide Sunucuya etkin bir bağlantı yeniden kurulur. Kalıcıyı gizleyin.
components-reconnect-failed Yeniden bağlantı büyük olasılıkla bir ağ hatası nedeniyle başarısız oldu. Yeniden bağlanmayı denemesi için JavaScript'i arayın window.Blazor.reconnect() .
components-reconnect-rejected Yeniden bağlantı reddedildi. Sunucuya ulaşıldı, ancak bağlantı reddedildi ve kullanıcının sunucudaki durumu kayboldu. Uygulamayı yeniden yüklemek için JavaScript'i arayın location.reload() . Bu bağlantı durumu aşağıdaki durumlarda oluşabilir:
  • Sunucu tarafı bağlantı hattında bir kilitlenme oluşur.
  • sunucunun kullanıcının durumunu bırakması için istemcinin bağlantısı yeterince uzundur. Kullanıcının bileşenlerinin örnekleri atılır.
  • Sunucu yeniden başlatılır veya uygulamanın çalışan işlemi geri dönüştürülür.

Sitenin CSS'sinde kalıcı öğe için özelliğini ayarlayarak transition-delay yeniden bağlantı görüntüsü görüntülenmeden önceki gecikmeyi özelleştirin. Aşağıdaki örnek, geçiş gecikmesini 500 ms 'den (varsayılan) 1.000 ms'ye (1 saniye) ayarlar.

wwwroot/app.css:

wwwroot/css/site.css:

#components-reconnect-modal {
    transition: visibility 0s linear 1000ms;
}

Geçerli yeniden bağlanma girişimini görüntülemek için, ile bir idcomponents-reconnect-current-attemptöğesi tanımlayın. Yeniden bağlanma yeniden denemesi sayısı üst sınırını görüntülemek için, ile bir idcomponents-reconnect-max-retriesöğesi tanımlayın. Aşağıdaki örnek, bu öğeleri önceki örnekten sonra yeniden bağlanma girişimi kalıcı öğesinin içine yerleştirir.

<div id="components-reconnect-modal">
    There was a problem with the connection!
    (Current reconnect attempt: 
    <span id="components-reconnect-current-attempt"></span> /
    <span id="components-reconnect-max-retries"></span>)
</div>

Özel yeniden bağlanma kalıcısı görüntülendiğinde, önceki koda göre aşağıdakine benzer bir içerik işler:

There was a problem with the connection! (Current reconnect attempt: 3 / 8)

Sunucu tarafı işleme

Varsayılan olarak, sunucuya istemci bağlantısı kurulmadan önce bileşenler sunucuda önceden oluşturulur. Daha fazla bilgi için bkz . Prerender ASP.NET Core Razor bileşenleri.

Varsayılan olarak, sunucuya istemci bağlantısı kurulmadan önce bileşenler sunucuda önceden oluşturulur. Daha fazla bilgi için bkz . ASP.NET Core'da Bileşen Etiketi Yardımcısı.

Sunucu tarafı devre etkinliğini izleme

üzerindeki CircuitHandleryöntemini kullanarak CreateInboundActivityHandler gelen bağlantı hattı etkinliğini izleyin. Gelen bağlantı hattı etkinliği, kullanıcı arabirimi olayları veya JavaScript-to-.NET birlikte çalışma çağrıları gibi tarayıcıdan sunucuya gönderilen herhangi bir etkinliktir.

Örneğin, istemcinin boşta olup olmadığını algılamak ve devre kimliğini (Circuit.Id):

using Microsoft.AspNetCore.Components.Server.Circuits;
using Microsoft.Extensions.Options;
using Timer = System.Timers.Timer;

public sealed class IdleCircuitHandler : CircuitHandler, IDisposable
{
    private Circuit? currentCircuit;
    private readonly ILogger logger;
    private readonly Timer timer;

    public IdleCircuitHandler(ILogger<IdleCircuitHandler> logger, 
        IOptions<IdleCircuitOptions> options)
    {
        timer = new Timer
        {
            Interval = options.Value.IdleTimeout.TotalMilliseconds,
            AutoReset = false
        };

        timer.Elapsed += CircuitIdle;
        this.logger = logger;
    }

    private void CircuitIdle(object? sender, System.Timers.ElapsedEventArgs e)
    {
        logger.LogInformation("{CircuitId} is idle", currentCircuit?.Id);
    }

    public override Task OnCircuitOpenedAsync(Circuit circuit, 
        CancellationToken cancellationToken)
    {
        currentCircuit = circuit;

        return Task.CompletedTask;
    }

    public override Func<CircuitInboundActivityContext, Task> CreateInboundActivityHandler(
        Func<CircuitInboundActivityContext, Task> next)
    {
        return context =>
        {
            timer.Stop();
            timer.Start();

            return next(context);
        };
    }

    public void Dispose() => timer.Dispose();
}

public class IdleCircuitOptions
{
    public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromMinutes(5);
}

public static class IdleCircuitHandlerServiceCollectionExtensions
{
    public static IServiceCollection AddIdleCircuitHandler(
        this IServiceCollection services, 
        Action<IdleCircuitOptions> configureOptions)
    {
        services.Configure(configureOptions);
        services.AddIdleCircuitHandler();

        return services;
    }

    public static IServiceCollection AddIdleCircuitHandler(
        this IServiceCollection services)
    {
        services.AddScoped<CircuitHandler, IdleCircuitHandler>();

        return services;
    }
}

Hizmeti dosyaya Program kaydedin. Aşağıdaki örnek, önceki uygulamayı test etmek için beş dakikadan beş saniyeye kadar varsayılan boşta kalma zaman aşımını yapılandırır IdleCircuitHandler :

builder.Services.AddIdleCircuitHandler(options => 
    options.IdleTimeout = TimeSpan.FromSeconds(5));

Bağlantı hattı etkinlik işleyicileri, kapsamı belirlenmiş Blazor hizmetlere diğer bağımlılık eklemeBlazor (DI) kapsamlarından erişmeye yönelik bir yaklaşım da sağlar. Daha fazla bilgi ve örnek için bkz:

Blazor Başlangıç

Web Uygulaması dosyasında bir Blazor uygulamanın SignalR bağlantı hattının el ile başlatılmasını App.razorBlazor yapılandırın:

Dosyada bir Blazor uygulamanın SignalR bağlantı hattının el ile başlatılmasını Pages/_Host.cshtml yapılandırın (Blazor Server):

Dosyada bir Blazor uygulamanın SignalR bağlantı hattının el ile başlatılmasını Pages/_Layout.cshtml yapılandırın (Blazor Server):

Dosyada bir Blazor uygulamanın SignalR bağlantı hattının el ile başlatılmasını Pages/_Host.cshtml yapılandırın (Blazor Server):

  • Betiğin etiketine <script>blazor.*.js bir autostart="false" öznitelik ekleyin.
  • Betik yüklendikten sonra ve kapanış </body> etiketinin Blazor içine çağıran Blazor.start() bir betik yerleştirin.

Devre dışı bırakıldığında autostart , uygulamanın devreye bağımlı olmayan herhangi bir yönü normal şekilde çalışır. Örneğin, istemci tarafı yönlendirme çalışır durumdadır. Ancak, bağlantı hattına bağlı olan herhangi bir özellik çağrılana kadar Blazor.start() çalışmaz. Uygulama davranışı, yerleşik bir bağlantı hattı olmadan öngörülemez. Örneğin, bağlantı hattı kesilirken bileşen yöntemleri yürütülememektedir.

Belge hazır olduğunda başlatma Blazor ve öğesine JS Promisezincirleme gibi daha fazla bilgi için bkz . ASP.NET Core Blazor başlatma.

İstemcide zaman aşımlarını ve Etkin Tutma'yi yapılandırma SignalR

İstemci için aşağıdaki değerleri yapılandırın:

  • withServerTimeout: Sunucu zaman aşımını milisaniye cinsinden yapılandırıyor. Bu zaman aşımı sunucudan ileti alınmadan sona ererse, bağlantı bir hatayla sonlandırılır. Varsayılan zaman aşımı değeri 30 saniyedir. Sunucu zaman aşımı, Etkin Tutma aralığına (withKeepAliveInterval ) atanan değerin en az iki katı olmalıdır.
  • withKeepAliveInterval: Etkin Tutma aralığını milisaniye cinsinden (sunucuya ping komutu göndermek için varsayılan aralık) yapılandırılır. Bu ayar, sunucunun bir istemcinin bilgisayarını ağdan çıkarması gibi sabit bağlantı kesilmelerini algılamasına olanak tanır. Ping, sunucu ping'leri kadar sık gerçekleşir. Sunucu beş saniyede bir ping atarsa, beş saniyede bir (5 saniye) daha 5000 düşük bir değer atar. Varsayılan değer 15 saniyedir. Etkin Tutma aralığı, sunucu zaman aşımına (withServerTimeout ) atanan değerin yarısından küçük veya buna eşit olmalıdır.

Aşağıdaki dosya örneğinde App.razor (Blazor Web App) varsayılan değerlerin ataması gösterilmektedir.

Blazor Web Uygulaması:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    circuit: {
      configureSignalR: function (builder) {
        builder.withServerTimeout(30000).withKeepAliveInterval(15000);
      }
    }
  });
</script>

Dosya (Blazor Server.NET 6'da ASP.NET Core dışındaki tüm sürümler) veya Pages/_Layout.cshtml dosya (Blazor Server.NET 6'da ASP.NET Core) için Pages/_Host.cshtml aşağıdaki örnek.

Blazor Server:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    configureSignalR: function (builder) {
        builder.withServerTimeout(30000).withKeepAliveInterval(15000);
  });
</script>

Yukarıdaki örnekte, {BLAZOR SCRIPT} yer tutucu betik yolu ve dosya adıdır Blazor . Betiğin konumu ve kullanılacak yol için bkz . ASP.NET Core Blazor proje yapısı.

Bir bileşende hub bağlantısı oluştururken, üzerinde HubConnectionBuilder(varsayılan: 30 saniye) ve KeepAliveInterval (varsayılan: 15 saniye) ayarlayın ServerTimeout . Yerleşik HubConnectionüzerinde HandshakeTimeout (varsayılan: 15 saniye) değerini ayarlayın. Aşağıdaki örnekte varsayılan değerlerin ataması gösterilmektedir:

protected override async Task OnInitializedAsync()
{
    hubConnection = new HubConnectionBuilder()
        .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
        .WithServerTimeout(TimeSpan.FromSeconds(30))
        .WithKeepAliveInterval(TimeSpan.FromSeconds(15))
        .Build();

    hubConnection.HandshakeTimeout = TimeSpan.FromSeconds(15);

    hubConnection.On<string, string>("ReceiveMessage", (user, message) => ...

    await hubConnection.StartAsync();
}

İstemci için aşağıdaki değerleri yapılandırın:

  • serverTimeoutInMilliseconds: Sunucu zaman aşımı milisaniye cinsinden. Bu zaman aşımı sunucudan ileti alınmadan sona ererse, bağlantı bir hatayla sonlandırılır. Varsayılan zaman aşımı değeri 30 saniyedir. Sunucu zaman aşımı, Etkin Tutma aralığına (keepAliveIntervalInMilliseconds ) atanan değerin en az iki katı olmalıdır.
  • keepAliveIntervalInMilliseconds: Sunucuya ping göndermek için varsayılan aralık. Bu ayar, sunucunun bir istemcinin bilgisayarını ağdan çıkarması gibi sabit bağlantı kesilmelerini algılamasına olanak tanır. Ping, sunucu ping'leri kadar sık gerçekleşir. Sunucu beş saniyede bir ping atarsa, beş saniyede bir (5 saniye) daha 5000 düşük bir değer atar. Varsayılan değer 15 saniyedir. Etkin Tutma aralığı, sunucu zaman aşımına (serverTimeoutInMilliseconds ) atanan değerin yarısından küçük veya buna eşit olmalıdır.

Dosya (Blazor Server.NET 6'da ASP.NET Core dışındaki tüm sürümler) veya Pages/_Layout.cshtml dosya (Blazor Server.NET 6'da ASP.NET Core) için Pages/_Host.cshtml aşağıdaki örnek:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    configureSignalR: function (builder) {
      let c = builder.build();
      c.serverTimeoutInMilliseconds = 30000;
      c.keepAliveIntervalInMilliseconds = 15000;
      builder.build = () => {
        return c;
      };
    }
  });
</script>

Yukarıdaki örnekte, {BLAZOR SCRIPT} yer tutucu betik yolu ve dosya adıdır Blazor . Betiğin konumu ve kullanılacak yol için bkz . ASP.NET Core Blazor proje yapısı.

Bir bileşende hub bağlantısı oluştururken, yerleşik HubConnectionüzerinde (varsayılan: 30 saniye), HandshakeTimeout (varsayılan: 15 saniye) ve KeepAliveInterval (varsayılan: 15 saniye) ayarlayın ServerTimeout . Aşağıdaki örnekte varsayılan değerlerin ataması gösterilmektedir:

protected override async Task OnInitializedAsync()
{
    hubConnection = new HubConnectionBuilder()
        .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
        .Build();

    hubConnection.ServerTimeout = TimeSpan.FromSeconds(30);
    hubConnection.HandshakeTimeout = TimeSpan.FromSeconds(15);
    hubConnection.KeepAliveInterval = TimeSpan.FromSeconds(15);

    hubConnection.On<string, string>("ReceiveMessage", (user, message) => ...

    await hubConnection.StartAsync();
}

Sunucu zaman aşımı () veya Etkin Tutma aralığı (ServerTimeoutKeepAliveInterval) değerlerini değiştirirken:

  • Sunucu zaman aşımı, Etkin Tutma aralığına atanan değerin en az iki katı olmalıdır.
  • Etkin Tutma aralığı, sunucu zaman aşımına atanan değerin yarısından küçük veya buna eşit olmalıdır.

Daha fazla bilgi için aşağıdaki makalelerin Genel dağıtım ve bağlantı hataları bölümlerine bakın:

Sunucu tarafı yeniden bağlantı işleyicisini değiştirme

Yeniden bağlantı işleyicisinin bağlantı hattı bağlantı olayları, aşağıdaki gibi özel davranışlar için değiştirilebilir:

  • Bağlantının bırakılıp bırakılmadiğini kullanıcıya bildirmek için.
  • Bir bağlantı hattı bağlandığında günlüğe kaydetme (istemciden) gerçekleştirmek için.

Bağlantı olaylarını değiştirmek için aşağıdaki bağlantı değişiklikleri için geri çağırmaları kaydedin:

  • Bırakılan bağlantılar kullanır onConnectionDown.
  • Kurulan/yeniden kurulan bağlantılar kullanır onConnectionUp.

onConnectionUp Hem hem de onConnectionDown belirtilmelidir.

Blazor Web Uygulaması:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    circuit: {
      reconnectionHandler: {
        onConnectionDown: (options, error) => console.error(error),
        onConnectionUp: () => console.log("Up, up, and away!")
      }
    }
  });
</script>

Blazor Server:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    reconnectionHandler: {
      onConnectionDown: (options, error) => console.error(error),
      onConnectionUp: () => console.log("Up, up, and away!")
    }
  });
</script>

Yukarıdaki örnekte, {BLAZOR SCRIPT} yer tutucu betik yolu ve dosya adıdır Blazor . Betiğin konumu ve kullanılacak yol için bkz . ASP.NET Core Blazor proje yapısı.

Sunucu tarafı yeniden bağlantı başarısız olduğunda sayfayı otomatik olarak yenile

Varsayılan yeniden bağlanma davranışı, yeniden bağlantı başarısız olduktan sonra kullanıcının sayfayı yenilemek için el ile işlem gerçekleştirmesini gerektirir. Ancak, sayfayı otomatik olarak yenilemek için özel bir yeniden bağlantı işleyicisi kullanılabilir:

App.razor:

Pages/_Host.cshtml:

<div id="reconnect-modal" style="display: none;"></div>
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script src="boot.js"></script>

Yukarıdaki örnekte, {BLAZOR SCRIPT} yer tutucu betik yolu ve dosya adıdır Blazor . Betiğin konumu ve kullanılacak yol için bkz . ASP.NET Core Blazor proje yapısı.

Aşağıdaki wwwroot/boot.js dosyayı oluşturun.

Blazor Web Uygulaması:

(() => {
  const maximumRetryCount = 3;
  const retryIntervalMilliseconds = 5000;
  const reconnectModal = document.getElementById('reconnect-modal');

  const startReconnectionProcess = () => {
    reconnectModal.style.display = 'block';

    let isCanceled = false;

    (async () => {
      for (let i = 0; i < maximumRetryCount; i++) {
        reconnectModal.innerText = `Attempting to reconnect: ${i + 1} of ${maximumRetryCount}`;

        await new Promise(resolve => setTimeout(resolve, retryIntervalMilliseconds));

        if (isCanceled) {
          return;
        }

        try {
          const result = await Blazor.reconnect();
          if (!result) {
            // The server was reached, but the connection was rejected; reload the page.
            location.reload();
            return;
          }

          // Successfully reconnected to the server.
          return;
        } catch {
          // Didn't reach the server; try again.
        }
      }

      // Retried too many times; reload the page.
      location.reload();
    })();

    return {
      cancel: () => {
        isCanceled = true;
        reconnectModal.style.display = 'none';
      },
    };
  };

  let currentReconnectionProcess = null;

  Blazor.start({
    circuit: {
      reconnectionHandler: {
        onConnectionDown: () => currentReconnectionProcess ??= startReconnectionProcess(),
        onConnectionUp: () => {
          currentReconnectionProcess?.cancel();
          currentReconnectionProcess = null;
        }
      }
    }
  });
})();

Blazor Server:

(() => {
  const maximumRetryCount = 3;
  const retryIntervalMilliseconds = 5000;
  const reconnectModal = document.getElementById('reconnect-modal');

  const startReconnectionProcess = () => {
    reconnectModal.style.display = 'block';

    let isCanceled = false;

    (async () => {
      for (let i = 0; i < maximumRetryCount; i++) {
        reconnectModal.innerText = `Attempting to reconnect: ${i + 1} of ${maximumRetryCount}`;

        await new Promise(resolve => setTimeout(resolve, retryIntervalMilliseconds));

        if (isCanceled) {
          return;
        }

        try {
          const result = await Blazor.reconnect();
          if (!result) {
            // The server was reached, but the connection was rejected; reload the page.
            location.reload();
            return;
          }

          // Successfully reconnected to the server.
          return;
        } catch {
          // Didn't reach the server; try again.
        }
      }

      // Retried too many times; reload the page.
      location.reload();
    })();

    return {
      cancel: () => {
        isCanceled = true;
        reconnectModal.style.display = 'none';
      },
    };
  };

  let currentReconnectionProcess = null;

  Blazor.start({
    reconnectionHandler: {
      onConnectionDown: () => currentReconnectionProcess ??= startReconnectionProcess(),
      onConnectionUp: () => {
        currentReconnectionProcess?.cancel();
        currentReconnectionProcess = null;
      }
    }
  });
})();

Blazor'ı başlatma hakkında daha fazla bilgi için bkz. ASP.NET Core Blazor'ı başlatma.

Sunucu tarafı yeniden bağlanma yeniden deneme sayısını ve aralığını ayarlama

Yeniden bağlanma yeniden deneme sayısını ve aralığını ayarlamak için, yeniden deneme sayısını (maxRetries) ve her yeniden deneme girişiminde izin verilen milisaniye cinsinden süreyi (retryIntervalMilliseconds) ayarlayın.

Blazor Web Uygulaması:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    circuit: {
      reconnectionOptions: {
        maxRetries: 3,
        retryIntervalMilliseconds: 2000
      }
    }
  });
</script>

Blazor Server:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    reconnectionOptions: {
      maxRetries: 3,
      retryIntervalMilliseconds: 2000
    }
  });
</script>

Yukarıdaki örnekte, {BLAZOR SCRIPT} yer tutucu betik yolu ve dosya adıdır Blazor . Betiğin konumu ve kullanılacak yol için bkz . ASP.NET Core Blazor proje yapısı.

Blazor'ı başlatma hakkında daha fazla bilgi için bkz. ASP.NET Core Blazor'ı başlatma.

Yeniden bağlantı kullanıcı arabiriminin ne zaman görüneceğini denetleme

Yeniden bağlantı kullanıcı arabiriminin ne zaman görüneceğini denetlemek aşağıdaki durumlarda yararlı olabilir:

  • Dağıtılan bir uygulama, iç ağ veya İnternet gecikmesinin neden olduğu ping zaman aşımları nedeniyle yeniden bağlantı kullanıcı arabirimini sık sık görüntüler ve gecikmeyi artırmak istiyorsunuz.
  • Bir uygulama, kullanıcılara bağlantının daha erken bırakıldığını bildirmelidir ve gecikmeyi kısaltmak istersiniz.

Yeniden bağlantı kullanıcı arabiriminin görünümünün zamanlaması, istemcide Etkin Tutma aralığının ve zaman aşımlarının ayarlanmasından etkilenir. Yeniden bağlanma kullanıcı arabirimi, istemcide sunucu zaman aşımına ulaşıldığında (withServerTimeoutİstemci yapılandırması bölümü) görüntülenir. Ancak değerini withServerTimeout değiştirmek için aşağıdaki kılavuzda açıklanan diğer Canlı Tutma, zaman aşımı ve el sıkışma ayarlarında değişiklik yapılması gerekir.

Aşağıdaki yönergeler için genel öneriler olarak:

  • Etkin Tutma aralığı, istemci ve sunucu yapılandırmaları arasında eşleşmelidir.
  • Zaman aşımları, Etkin Tutma aralığına atanan değerin en az iki katı olmalıdır.

Sunucu yapılandırması

Aşağıdakileri ayarlayın:

  • ClientTimeoutInterval (varsayılan: 30 saniye): Sunucu bağlantıyı kapatmadan önce zaman penceresi istemcilerinin bir ileti göndermesi gerekir.
  • HandshakeTimeout (varsayılan: 15 saniye): sunucu tarafından istemciler tarafından gelen el sıkışma isteklerinin zaman aşımına uğrarken kullandığı aralık.
  • KeepAliveInterval (varsayılan: 15 saniye): Sunucu tarafından bağlı istemcilere canlı tutma pingleri göndermek için kullanılan aralık. İstemcide sunucunun değeriyle eşleşmesi gereken bir Etkin Tutma aralığı ayarı da olduğunu unutmayın.

ClientTimeoutInterval ve HandshakeTimeout değeri artırılabilir ve KeepAliveInterval aynı kalabilir. Önemli nokta, değerleri değiştirirseniz zaman aşımlarının Etkin Tutma aralığının değerinin en az iki katı olduğundan ve Etkin Tutma aralığının sunucu ile istemci arasında eşleştiğinden emin olmanızdır. Daha fazla bilgi için istemcide zaman aşımlarını ve Etkin Tutma'yı yapılandırma SignalR bölümüne bakın.

Aşağıdaki örnekte:

  • ClientTimeoutInterval değeri 60 saniyeye çıkarılır (varsayılan değer: 30 saniye).
  • HandshakeTimeout değeri 30 saniyeye çıkarılır (varsayılan değer: 15 saniye).
  • KeepAliveInterval geliştirici kodunda ayarlanmadı ve varsayılan değeri olan 15 saniyeyi kullanır. Etkin Tutma aralığının değerinin azaltılması, iletişim pinglerinin sıklığını artırır ve bu da uygulama, sunucu ve ağ üzerindeki yükü artırır. Etkin Tutma aralığını düşürürken düşük performans göstermemek için dikkatli olunmalıdır.

BlazorSunucu projesinin Program dosyasında web uygulaması (.NET 8 veya üzeri):

builder.Services.AddRazorComponents().AddInteractiveServerComponents()
    .AddHubOptions(options =>
{
    options.ClientTimeoutInterval = TimeSpan.FromSeconds(60);
    options.HandshakeTimeout = TimeSpan.FromSeconds(30);
});

Blazor Serverdosyasında:Program

builder.Services.AddServerSideBlazor()
    .AddHubOptions(options =>
    {
        options.ClientTimeoutInterval = TimeSpan.FromSeconds(60);
        options.HandshakeTimeout = TimeSpan.FromSeconds(30);
    });

Daha fazla bilgi için Sunucu tarafı bağlantı hattı işleyici seçenekleri bölümüne bakın.

İstemci yapılandırması

Aşağıdakileri ayarlayın:

  • withServerTimeout (varsayılan: 30 saniye): Bağlantı hattının hub bağlantısı için milisaniye olarak belirtilen sunucu zaman aşımını yapılandırılır.
  • withKeepAliveInterval (varsayılan: 15 saniye): Bağlantının Etkin Tutma iletilerini gönderdiği milisaniye cinsinden belirtilen aralık.

Sunucu zaman aşımı artırılabilir ve Etkin Tutma aralığı aynı kalabilir. Önemli nokta, değerleri değiştirirseniz sunucu zaman aşımının Etkin Tutma aralığının değerinin en az iki katı olduğundan ve Etkin Tutma aralığı değerlerinin sunucu ile istemci arasında eşleştiğinden emin olmanızdır. Daha fazla bilgi için istemcide zaman aşımlarını ve Etkin Tutma'yı yapılandırma SignalR bölümüne bakın.

Aşağıdaki başlangıç yapılandırma örneğinde (betiğin Blazorkonumu), sunucu zaman aşımı için 60 saniyelik özel bir değer kullanılır. Etkin Tutma aralığı (withKeepAliveInterval) ayarlanmadı ve varsayılan değeri olan 15 saniyeyi kullanır.

Blazor Web Uygulaması:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    circuit: {
      configureSignalR: function (builder) {
        builder.withServerTimeout(60000);
      }
    }
  });
</script>

Blazor Server:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    configureSignalR: function (builder) {
      builder.withServerTimeout(60000);
    }
  });
</script>

Bir bileşende hub bağlantısı oluştururken, üzerinde sunucu zaman aşımını (WithServerTimeoutvarsayılan: 30 saniye) HubConnectionBuilderayarlayın. Yerleşik HubConnectionüzerinde HandshakeTimeout (varsayılan: 15 saniye) değerini ayarlayın. Zaman aşımlarının Etkin Tutma aralığınınWithKeepAliveInterval/KeepAliveInterval () en az iki katı olduğunu ve Etkin Tutma değerinin sunucu ile istemci arasında eşleşip eşleşmediğini onaylayın.

Aşağıdaki örnek, ile öğreticisindeki IndexSignalR bileşeni temel alır.Blazor Sunucu zaman aşımı 60 saniyeye, el sıkışma zaman aşımı ise 30 saniyeye çıkarılır. Etkin Tutma aralığı ayarlanmadı ve varsayılan değeri olan 15 saniyeyi kullanır.

protected override async Task OnInitializedAsync()
{
    hubConnection = new HubConnectionBuilder()
        .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
        .WithServerTimeout(TimeSpan.FromSeconds(60))
        .Build();

    hubConnection.HandshakeTimeout = TimeSpan.FromSeconds(30);

    hubConnection.On<string, string>("ReceiveMessage", (user, message) => ...

    await hubConnection.StartAsync();
}

Aşağıdakileri ayarlayın:

  • serverTimeoutInMilliseconds (varsayılan: 30 saniye): Bağlantı hattının hub bağlantısı için milisaniye olarak belirtilen sunucu zaman aşımını yapılandırılır.
  • keepAliveIntervalInMilliseconds (varsayılan: 15 saniye): Bağlantının Etkin Tutma iletilerini gönderdiği milisaniye cinsinden belirtilen aralık.

Sunucu zaman aşımı artırılabilir ve Etkin Tutma aralığı aynı kalabilir. Önemli nokta, değerleri değiştirirseniz sunucu zaman aşımının Etkin Tutma aralığının değerinin en az iki katı olduğundan ve Etkin Tutma aralığı değerlerinin sunucu ile istemci arasında eşleştiğinden emin olmanızdır. Daha fazla bilgi için istemcide zaman aşımlarını ve Etkin Tutma'yı yapılandırma SignalR bölümüne bakın.

Aşağıdaki başlangıç yapılandırma örneğinde (betiğin Blazorkonumu), sunucu zaman aşımı için 60 saniyelik özel bir değer kullanılır. Etkin Tutma aralığı (keepAliveIntervalInMilliseconds) ayarlanmadı ve varsayılan değeri olan 15 saniyeyi kullanır.

Pages/_Host.cshtml içinde:

<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
  Blazor.start({
    configureSignalR: function (builder) {
      let c = builder.build();
      c.serverTimeoutInMilliseconds = 60000;
      builder.build = () => {
        return c;
      };
    }
  });
</script>

Bir bileşende hub bağlantısı oluştururken, yerleşik HubConnectionüzerinde (varsayılan: 30 saniye) ve HandshakeTimeout (varsayılan: 15 saniye) ayarlayın ServerTimeout . Zaman aşımlarının Etkin Tutma aralığının en az iki katı olduğunu onaylayın. Etkin Tutma aralığının sunucu ve istemci arasında eşleşip eşleşmediğini onaylayın.

Aşağıdaki örnek, ile öğreticisindeki IndexSignalR bileşeni temel alır.Blazor ServerTimeout 60 saniyeye HandshakeTimeout ve 30 saniyeye yükseltilir. Etkin Tutma aralığı (KeepAliveInterval) ayarlanmadı ve varsayılan değeri olan 15 saniyeyi kullanır.

protected override async Task OnInitializedAsync()
{
    hubConnection = new HubConnectionBuilder()
        .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
        .Build();

    hubConnection.ServerTimeout = TimeSpan.FromSeconds(60);
    hubConnection.HandshakeTimeout = TimeSpan.FromSeconds(30);

    hubConnection.On<string, string>("ReceiveMessage", (user, message) => ...

    await hubConnection.StartAsync();
}

Bağlantı hattının Blazor istemciyle bağlantısını kesme

Varsayılan olarak, sayfa olayı tetiklendiğindeunloadbağlantı Blazor hattı kesilir. İstemcideki diğer senaryoların bağlantı hattını kesmek için uygun olay işleyicisinde çağırın Blazor.disconnect . Aşağıdaki örnekte, sayfa gizli olduğunda bağlantı hattının bağlantısı kesilir (pagehide olay):

window.addEventListener('pagehide', () => {
  Blazor.disconnect();
});

Blazor'ı başlatma hakkında daha fazla bilgi için bkz. ASP.NET Core Blazor'ı başlatma.

Sunucu tarafı devre işleyicisi

Kullanıcının bağlantı hattının durumundaki değişikliklerde kod çalıştırmaya olanak tanıyan bir bağlantı hattı işleyicisi tanımlayabilirsiniz. Bağlantı hattı işleyicisi, sınıfından CircuitHandler türetilerek ve sınıfı uygulamanın hizmet kapsayıcısında kaydederek uygulanır. Aşağıdaki bağlantı hattı işleyicisi örneği açık SignalR bağlantıları izler.

TrackingCircuitHandler.cs:

using Microsoft.AspNetCore.Components.Server.Circuits;

public class TrackingCircuitHandler : CircuitHandler
{
    private HashSet<Circuit> circuits = new();

    public override Task OnConnectionUpAsync(Circuit circuit, 
        CancellationToken cancellationToken)
    {
        circuits.Add(circuit);

        return Task.CompletedTask;
    }

    public override Task OnConnectionDownAsync(Circuit circuit, 
        CancellationToken cancellationToken)
    {
        circuits.Remove(circuit);

        return Task.CompletedTask;
    }

    public int ConnectedCircuits => circuits.Count;
}

Bağlantı hattı işleyicileri DI kullanılarak kaydedilir. Kapsamlı örnekler, bir bağlantı hattının örneği başına oluşturulur. TrackingCircuitHandler Yukarıdaki örnekte kullanılarak, tüm devrelerin durumunun izlenmesi gerektiğinden tek bir hizmet oluşturulur.

Program dosyasında:

builder.Services.AddSingleton<CircuitHandler, TrackingCircuitHandler>();

Startup.csiçindeStartup.ConfigureServices:

services.AddSingleton<CircuitHandler, TrackingCircuitHandler>();

Özel devre işleyicisinin yöntemleri işlenmeyen bir özel durum oluşturursa, özel durum devre için önemli olur. İşleyicinin kodundaki veya çağrılan yöntemlerdeki özel durumları tolere etmek için, kodu hata işleme ve günlüğe kaydetme ile bir veya daha fazla try-catch deyimde sarmalayın.

Kullanıcının bağlantısı kesildiği ve çerçevenin bağlantı hattı durumunu temizlediği için bir bağlantı hattı sona erdiğinde, çerçeve devrenin DI kapsamını atmış olur. Kapsamın atılması, uygulayan System.IDisposabledevre kapsamlı DI hizmetlerini atacaktır. Herhangi bir DI hizmeti elden çıkarma sırasında işlenmeyen bir özel durum oluşturursa, çerçeve özel durumu günlüğe kaydeder. Daha fazla bilgi için bkz . ASP.NET Core Blazor bağımlılık ekleme.

Özel hizmetler için kullanıcıları yakalamak için sunucu tarafı bağlantı hattı işleyicisi

CircuitHandler'den AuthenticationStateProvider bir kullanıcı yakalamak ve bu kullanıcıyı bir hizmette ayarlamak için kullanın. Daha fazla bilgi ve örnek kod için bkz . Sunucu tarafı ASP.NET Core Blazor ek güvenlik senaryoları.

Etkileşimli Sunucu bileşenleri kalmadığında devrelerin kapatılması

Etkileşimli Sunucu bileşenleri, tarayıcıyla bağlantı hattı adı verilen gerçek zamanlı bir bağlantı kullanarak web kullanıcı arabirimi olaylarını işler. Bir kök Etkileşimli Sunucu bileşeni işlendiğinde bir bağlantı hattı ve ilişkili durumu oluşturulur. Bağlantı hattı, sayfada kalan Etkileşimli Sunucu bileşenleri olmadığında kapatılır ve bu da sunucu kaynaklarını serbest bırakır.

IHttpContextAccessor/HttpContextbileşenlerde Razor

IHttpContextAccessor geçerli HttpContext bir kullanılabilir değer olmadığından etkileşimli işlemeden kaçınılmalıdır.

IHttpContextAccessor sunucuda statik olarak işlenen bileşenler için kullanılabilir. Ancak mümkünse bundan kaçınmanızı öneririz.

HttpContext, üst bilgileri veya bileşendeki Components/App.razordiğer özellikleri () inceleme ve değiştirme gibi genel görevler için yalnızca statik olarak işlenmiş kök bileşenlerdeApp basamaklı parametre olarak kullanılabilir. Değer her zaman null etkileşimli işleme içindir.

[CascadingParameter]
public HttpContext? HttpContext { get; set; }

öğesinin HttpContext etkileşimli bileşenlerde gerekli olduğu senaryolar için verileri sunucudan kalıcı bileşen durumu aracılığıyla akışla aktarmanızı öneririz. Daha fazla bilgi için bkz . Sunucu tarafı ASP.NET Core Blazor ek güvenlik senaryoları.

Sunucu tarafı uygulamaların bileşenlerinde doğrudan veya dolaylı olarak kullanmayınIHttpContextAccessor./HttpContextRazorBlazor Blazor uygulamalar ASP.NET Core işlem hattı bağlamının dışında çalışır. HttpContext içinde kullanılabilir IHttpContextAccessorolması garanti edilmez ve HttpContext uygulamayı başlatan Blazor bağlamı tutması garanti edilmez.

İstek durumunu Blazor uygulamaya geçirmek için önerilen yaklaşım, uygulamanın ilk işlemesi sırasında kök bileşen parametrelerinden geçer. Alternatif olarak uygulama, kök bileşenin uygulama genelinde kullanılmak üzere başlatma yaşam döngüsü olayında verileri kapsamlı bir hizmete kopyalayabilir. Daha fazla bilgi için bkz . Sunucu tarafı ASP.NET Core Blazor ek güvenlik senaryoları.

Sunucu tarafı Blazor güvenliğinin kritik bir yönü, belirli bir bağlantı hattına bağlı olan kullanıcının, bağlantı hattı oluşturulduktan sonra Blazor bir noktada güncelleştirilebilir ancak IHttpContextAccessorgüncelleştirilmeyebilir. Özel hizmetlerle bu durumu ele alma hakkında daha fazla bilgi için bkz . Sunucu tarafı ASP.NET Çekirdek Blazor ek güvenlik senaryoları.

Ek sunucu tarafı kaynakları