Sdílet prostřednictvím


Hostování a nasazení aplikací na straně Blazor serveru

Poznámka:

Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 10 tohoto článku.

Výstraha

Tato verze ASP.NET Core již není podporována. Pro více informací se podívejte na Zásady podpory .NET a .NET Core. Aktuální vydání tohoto článku najdete v verzi .NET 9.

Tento článek vysvětluje, jak hostovat a nasazovat aplikaceBlazorBlazor Web App na straně Blazor Server serveru pomocí ASP.NET Core.

Hodnoty konfigurace hostitele

Aplikace na straně Blazor serveru můžou přijímat hodnoty konfigurace obecného hostitele.

Nasazení

Použití modelu Blazor hostování na straně serveru se provádí na serveru z aplikace ASP.NET Core. Aktualizace uživatelského rozhraní, zpracování událostí a volání JavaScriptu SignalR se zpracovávají přes připojení.

Vyžaduje se webový server, který může hostovat aplikaci ASP.NET Core. Visual Studio obsahuje šablonu projektu aplikace na straně serveru. Další informace o Blazor šablonách projektů najdete v tématu ASP.NET Blazor Základní struktura projektu.

Publikujte aplikaci v konfiguraci vydané verze a nasaďte obsah bin/Release/{TARGET FRAMEWORK}/publish složky, kde {TARGET FRAMEWORK} zástupný symbol představuje cílovou architekturu.

Škálovatelnost

Při zvažování škálovatelnosti jednoho serveru (vertikální navýšení kapacity) je paměť dostupná pro aplikaci pravděpodobně prvním prostředkem, který aplikace vyčerpá, protože se zvýší požadavky uživatelů. Dostupná paměť na serveru má vliv na:

  • Počet aktivních okruhů, které může server podporovat.
  • Latence uživatelského rozhraní v klientovi

Pokyny k vytváření zabezpečených a škálovatelných aplikací na straně Blazor serveru najdete v následujících zdrojích informací:

Každý okruh používá přibližně 250 kB paměti pro minimální aplikaci ve stylu Hello World. Velikost okruhu závisí na kódu aplikace a požadavcích na údržbu stavu spojených s jednotlivými komponentami. Doporučujeme měřit požadavky na prostředky během vývoje vaší aplikace a infrastruktury, ale následující směrný plán může být výchozím bodem při plánování cíle nasazení: Pokud očekáváte, že vaše aplikace bude podporovat 5 000 souběžných uživatelů, zvažte rozpočtování alespoň 1,3 GB paměti serveru do aplikace (nebo přibližně 273 kB na uživatele).

Blazor WebAssembly Přednačítání statických prvků

Komponenta ResourcePreloader v hlavičce obsahu komponenty App (App.razor) slouží k referenci Blazor statických prostředků. Komponenta se umístí za značku základní adresy URL (<base>):

<ResourcePreloader />

Součást Razor se používá místo <link> prvků, protože:

  • Komponenta umožňuje nastavit základní adresu URL (<base> hodnotu atributu značky href), aby správně identifikovala kořen aplikace Blazor v aplikaci ASP.NET Core.
  • Tuto funkci můžete odebrat odebráním značky ResourcePreloader komponenty ze App komponenty. To je užitečné v případech, kdy aplikace k úpravě loadBootResource adres URL používá zpětné volání.

SignalR Konfigurace

SignalRPodmínky hostování a škálování se vztahují na Blazor aplikace, které používají SignalR.

Další informace o SignalRBlazor aplikacích, včetně pokynů ke konfiguraci, najdete v ASP.NET základních BlazorSignalR doprovodných materiálech.

Přenosy

Blazor funguje nejlépe při použití protokolu WebSocket jako SignalR přenosu kvůli nižší latenci, lepší spolehlivosti a lepšímu zabezpečení. Dlouhé dotazování se používá SignalR , když webSockets není k dispozici nebo když je aplikace explicitně nakonfigurovaná tak, aby používala dlouhé dotazování.

Pokud se používá dlouhé dotazování, zobrazí se upozornění konzoly:

Připojení přes WebSocket se nezdařilo pomocí náhradního přenosu Long Polling. Příčinou může být blokování připojení vpn nebo proxy serverem.

Globální nasazení a selhání připojení

Doporučení pro globální nasazení do geografických datových center:

  • Nasaďte aplikaci do oblastí, ve kterých se nachází většina uživatelů.
  • Vezměte v úvahu zvýšenou latenci provozu napříč kontinenty. Pokud chcete řídit vzhled uživatelského rozhraní pro opětovné připojení, přečtěte si pokyny Blazorpro ASP.NET CoreSignalR.
  • Zvažte použití SignalR Azure.

Azure App Service

Hostování ve službě Aplikace Azure Vyžaduje konfiguraci pro webSockets a spřažení relací, označované také jako spřažení směrování požadavků aplikace (ARR).

Poznámka:

Blazor Aplikace ve službě Aplikace Azure Nevyžaduje SignalR Azure.

Pro registraci aplikace ve službě Aplikace Azure Service povolte následující:

  • WebSockety umožňující přenos WebSockets do funkce. Výchozí nastavení je Vypnuto.
  • Spřažení relace pro směrování požadavků od uživatele zpět do stejné instance služby App Service. Výchozí nastavení je Zapnuto.
  1. Na webu Azure Portal přejděte do webové aplikace ve službě App Services.
  2. Otevřete >.
  3. Nastavte webové sokety na Zapnuto.
  4. Ověřte, že je spřažení relace nastavené na Zapnuto.

Služba Azure SignalR

Volitelná služba Azure funguje ve spojení s rozbočovačem aplikace pro škálování serverové aplikace na velký počet souběžných připojení. Globální dosah služby a vysoce výkonná datová centra navíc výrazně pomáhají snížit latenci kvůli zeměpisné poloze.

Služba se nevyžaduje pro Blazor aplikace hostované ve službě Aplikace Azure Service nebo Azure Container Apps, ale může být užitečná v jiných hostitelských prostředích:

  • Pro usnadnění škálování kapacity připojení.
  • Řízení globální distribuce

Služba Azure SignalR se sadou SDK verze 1.26.1 nebo novější podporuje SignalR stavové opětovné připojení (WithStatefulReconnect).

V případě, že aplikace používá dlouhé dotazování nebo se vrátí k dlouhému dotazování místo webSocketů, možná budete muset nakonfigurovat maximální interval dotazování (MaxPollIntervalInSecondsvýchozí nastavení: 5 sekund, limit: 1–300 sekund), který definuje maximální povolený interval dotazování pro připojení Long Polling ve službě Azure SignalR . Pokud další požadavek na hlasování nedorazí do maximálního intervalu dotazování, služba zavře připojení klienta.

Pokyny k přidání služby jako závislosti do produkčního nasazení najdete v tématu Publikování aplikace ASP.NET Core SignalR do služby Aplikace Azure Service.

Další informace najdete tady:

Azure Container Apps

Podrobnější zkoumání škálování aplikací na straně Blazor serveru ve službě Azure Container Apps najdete v tématu Škálování aplikací ASP.NET Core Apps v Azure. Tento kurz vysvětluje, jak vytvořit a integrovat služby potřebné k hostování aplikací v Azure Container Apps. V této části jsou uvedeny také základní kroky.

  1. Podle pokynů v spřažení relací v Azure Container Apps (dokumentace k Azure) nakonfigurujte službu Azure Container Apps pro spřažení relací.

  2. Služba ASP.NET Core Data Protection (DP) musí být nakonfigurovaná tak, aby uchovávala klíče v centralizované lokalitě, ke které mají přístup všechny instance kontejneru. Klíče je možné ukládat ve službě Azure Blob Storage a chránit je pomocí služby Azure Key Vault. Služba DP používá klíče k deserializaci Razor komponent. Pokud chcete nakonfigurovat službu DP tak, aby používala službu Azure Blob Storage a Azure Key Vault, projděte si následující balíčky NuGet:

    Poznámka:

    Pokyny k přidávání balíčků do aplikací .NET najdete v článcích v části Instalace a správa balíčků na webu Pracovní postup používání balíčků (dokumentace k NuGetu). Ověřte správné verze balíčků na NuGet.org.

  3. Aktualizujte Program.cs následujícím zvýrazněným kódem:

    using Azure.Identity;
    using Microsoft.AspNetCore.DataProtection;
    using Microsoft.Extensions.Azure;
    
    var builder = WebApplication.CreateBuilder(args);
    var BlobStorageUri = builder.Configuration["AzureURIs:BlobStorage"];
    var KeyVaultURI = builder.Configuration["AzureURIs:KeyVault"];
    
    builder.Services.AddRazorPages();
    builder.Services.AddHttpClient();
    builder.Services.AddServerSideBlazor();
    
    builder.Services.AddAzureClientsCore();
    
    builder.Services.AddDataProtection()
                    .PersistKeysToAzureBlobStorage(new Uri(BlobStorageUri),
                                                    new DefaultAzureCredential())
                    .ProtectKeysWithAzureKeyVault(new Uri(KeyVaultURI),
                                                    new DefaultAzureCredential());
    var app = builder.Build();
    
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }
    
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.UseAuthorization();
    
    app.MapRazorPages();
    
    app.Run();
    

    Předchozí změny umožňují aplikaci spravovat službu DP pomocí centralizované škálovatelné architektury. DefaultAzureCredential zjistí spravovanou identitu aplikace kontejneru po nasazení kódu do Azure a použije ji k připojení k úložišti objektů blob a trezoru klíčů aplikace.

  4. Pokud chcete vytvořit spravovanou identitu aplikace kontejneru a udělit jí přístup k úložišti objektů blob a trezoru klíčů, proveďte následující kroky:

    1. Na webu Azure Portal přejděte na stránku přehledu aplikace kontejneru.
    2. V levém navigačním panelu vyberte Konektor služby.
    3. V horním navigačním panelu vyberte + Vytvořit .
    4. V rozevírací nabídce Vytvořit připojení zadejte následující hodnoty:
      • Kontejner: Vyberte aplikaci kontejneru, kterou jste vytvořili pro hostování aplikace.
      • Typ služby: Vyberte úložiště objektů blob.
      • Předplatné: Vyberte předplatné, které vlastní aplikaci kontejneru.
      • Název připojení: Zadejte název .scalablerazorstorage
      • Typ klienta: Vyberte .NET a pak vyberte Další.
    5. Vyberte systémem přiřazené spravované identity a poté vyberte Další.
    6. Použijte výchozí nastavení sítě a vyberte Další.
    7. Jakmile Azure ověří nastavení, vyberte Vytvořit.

    Opakujte předchozí nastavení trezoru klíčů. Na kartě Základy vyberte příslušnou službu trezoru klíčů a klíč.

Poznámka:

Předchozí příklad používá DefaultAzureCredential ke zjednodušení ověřování při vývoji aplikací, které se nasazují do Azure zkombinováním přihlašovacích údajů používaných v hostitelských prostředích Azure s přihlašovacími údaji použitými v místním vývoji. Při přechodu na produkci je lepší volbou alternativa, například ManagedIdentityCredential. Další informace najdete v tématu Ověřování aplikací .NET hostovaných v Azure v prostředcích Azure pomocí spravované identity přiřazené systémem.

služba IIS

Při použití služby IIS povolte:

Další informace najdete v doprovodných materiálech a externích odkazech prostředků IIS v tématu Publikování aplikace ASP.NET Core do služby IIS.

Kubernetes

Vytvořte definici příchozího přenosu dat s následujícími poznámkami Kubernetes pro spřažení relací:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: <ingress-name>
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "affinity"
    nginx.ingress.kubernetes.io/session-cookie-expires: "14400"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "14400"

Linux na serveru Nginx

Postupujte podle pokynů pro aplikaci ASP.NET Core s následujícími změnami:

  • location Změňte cestu z /hubroute (location /hubroute { ... }) na kořenovou cestu / (location / { ... }).
  • Odeberte konfiguraci pro vyrovnávání paměti proxy serveru (proxy_buffering off;), protože nastavení platí jen pro události odeslané serverem (SSE), které nejsou relevantní pro interakce mezi klientem a serverem aplikace Blazor.

Další informace a pokyny ke konfiguraci najdete v následujících zdrojích informací:

Linux na serveru Apache

Pokud chcete hostovat aplikaci za Apache v Linuxu Blazor , nakonfigurujte ProxyPass provoz HTTP a WebSockets.

V následujícím příkladu:

  • Kestrel server běží na hostitelském počítači.
  • Aplikace naslouchá provozu na portu 5000.
ProxyPreserveHost   On
ProxyPassMatch      ^/_blazor/(.*) http://localhost:5000/_blazor/$1
ProxyPass           /_blazor ws://localhost:5000/_blazor
ProxyPass           / http://localhost:5000/
ProxyPassReverse    / http://localhost:5000/

Povolte následující moduly:

a2enmod   proxy
a2enmod   proxy_wstunnel

Zkontrolujte chyby webSocket v konzole prohlížeče. Ukázkové chyby:

  • Firefox nemůže navázat připojení k serveru na adrese ws://the-domain-name.tld/_blazor?id=XXX
  • Chyba: Přenos WebSockets se nepovedlo spustit: Chyba: Při přenosu došlo k chybě.
  • Chyba: Spuštění přenosu LongPolling: TypeError: this.transport není definován
  • Chyba: Nelze se připojit k serveru s žádným z dostupných přenosů. WebSockety selhaly
  • Chyba: Nelze odeslat data, pokud připojení není ve stavu Připojeno.

Další informace a pokyny ke konfiguraci najdete v následujících zdrojích informací:

Měření latence sítě

JS K měření latence sítě je možné použít interoperabilitu, jak ukazuje následující příklad.

MeasureLatency.razor:

@inject IJSRuntime JS

<h2>Measure Latency</h2>

@if (latency is null)
{
    <span>Calculating...</span>
}
else
{
    <span>@(latency.Value.TotalMilliseconds)ms</span>
}

@code {
    private DateTime startTime;
    private TimeSpan? latency;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            startTime = DateTime.UtcNow;
            var _ = await JS.InvokeAsync<string>("toString");
            latency = DateTime.UtcNow - startTime;
            StateHasChanged();
        }
    }
}
@inject IJSRuntime JS

<h2>Measure Latency</h2>

@if (latency is null)
{
    <span>Calculating...</span>
}
else
{
    <span>@(latency.Value.TotalMilliseconds)ms</span>
}

@code {
    private DateTime startTime;
    private TimeSpan? latency;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            startTime = DateTime.UtcNow;
            var _ = await JS.InvokeAsync<string>("toString");
            latency = DateTime.UtcNow - startTime;
            StateHasChanged();
        }
    }
}
@inject IJSRuntime JS

<h2>Measure Latency</h2>

@if (latency is null)
{
    <span>Calculating...</span>
}
else
{
    <span>@(latency.Value.TotalMilliseconds)ms</span>
}

@code {
    private DateTime startTime;
    private TimeSpan? latency;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            startTime = DateTime.UtcNow;
            var _ = await JS.InvokeAsync<string>("toString");
            latency = DateTime.UtcNow - startTime;
            StateHasChanged();
        }
    }
}
@inject IJSRuntime JS

<h2>Measure Latency</h2>

@if (latency is null)
{
    <span>Calculating...</span>
}
else
{
    <span>@(latency.Value.TotalMilliseconds)ms</span>
}

@code {
    private DateTime startTime;
    private TimeSpan? latency;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            startTime = DateTime.UtcNow;
            var _ = await JS.InvokeAsync<string>("toString");
            latency = DateTime.UtcNow - startTime;
            StateHasChanged();
        }
    }
}
@inject IJSRuntime JS

@if (latency is null)
{
    <span>Calculating...</span>
}
else
{
    <span>@(latency.Value.TotalMilliseconds)ms</span>
}

@code {
    private DateTime startTime;
    private TimeSpan? latency;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            startTime = DateTime.UtcNow;
            var _ = await JS.InvokeAsync<string>("toString");
            latency = DateTime.UtcNow - startTime;
            StateHasChanged();
        }
    }
}

Pro přiměřené uživatelské rozhraní doporučujeme trvalou latenci uživatelského rozhraní 250 ms nebo méně.