Hosten und Bereitstellen [Blazor ServerHost and deploy [Blazor Server

Von Luke Latham, Rainer Stropek und Daniel RothBy Luke Latham, Rainer Stropek, and Daniel Roth

HostkonfigurationswerteHost configuration values

[Blazor Server-Apps können generische Hostkonfigurationswerte akzeptieren.[Blazor Server apps can accept Generic Host configuration values.

BereitstellungDeployment

Mit dem [Blazor Server-Hostingmodell wird [Blazor in einer ASP.NET Core-App auf dem Server ausgeführt.Using the [Blazor Server hosting model, [Blazor is executed on the server from within an ASP.NET Core app. Benutzeroberflächenupdates, Ereignisbehandlung und JavaScript-Aufrufe werden über eine [SignalR-Verbindung verarbeitet.UI updates, event handling, and JavaScript calls are handled over a [SignalR connection.

Hierfür wird ein Webserver benötigt, der eine ASP.NET Core-App hosten kann.A web server capable of hosting an ASP.NET Core app is required. Visual Studio enthält die Projektvorlage der [Blazor Server-App (oder die blazorserverside-Vorlage bei Verwendung des Befehls dotnet new).Visual Studio includes the [Blazor Server App project template (blazorserverside template when using the dotnet new command).

SkalierbarkeitScalability

Planen Sie eine Bereitstellung, um die verfügbare Infrastruktur für eine [Blazor Server-App optimal zu nutzen.Plan a deployment to make the best use of the available infrastructure for a [Blazor Server app. Sehen Sie sich die folgenden Ressourcen an, um die Skalierbarkeit von [Blazor Server-Apps zu behandeln:See the following resources to address [Blazor Server app scalability:

BereitstellungsserverDeployment server

Wenn Sie die Skalierbarkeit eines einzelnen Servers in Erwägung ziehen (zentrales Hochskalieren), ist der für eine App verfügbare Arbeitsspeicher wahrscheinlich die erste Ressource, die die App erschöpft, wenn sich die Benutzeranforderungen erhöhen.When considering the scalability of a single server (scale up), the memory available to an app is likely the first resource that the app will exhaust as user demands increase. Der verfügbare Arbeitsspeicher auf dem Server wirkt sich auf Folgendes aus:The available memory on the server affects the:

  • Anzahl der aktiven Verbindungen, die ein Server unterstützen kann.Number of active circuits that a server can support.
  • Benutzeroberflächenlatenz auf dem Client.UI latency on the client.

Anleitungen zum Erstellen sicherer und skalierbarer [Blazor Server-Apps finden Sie unter Leitfaden zur Bedrohungsabwehr für [Blazor Server in ASP.NET Core.For guidance on building secure and scalable [Blazor server apps, see Leitfaden zur Bedrohungsabwehr für [Blazor Server in ASP.NET Core.

Jede Verbindung verwendet ungefähr 250 KB Arbeitsspeicher für eine minimale App im Hello World-Stil.Each circuit uses approximately 250 KB of memory for a minimal Hello World-style app. Die Größe einer Verbindung hängt vom App-Code und den Zustandsverwaltungsanforderungen der einzelnen Komponenten ab.The size of a circuit depends on the app's code and the state maintenance requirements associated with each component. Sie sollten die Ressourcenanforderungen während der Entwicklung für Ihre App und die Infrastruktur messen, aber die folgende Baseline kann ein Ausgangspunkt zur Planung des Bereitstellungsziels sein: Wenn Sie davon ausgehen, dass Ihre App 5.000 gleichzeitige Benutzer unterstützt, sollten Sie erwägen, mindestens 1,3 GB Serverarbeitsspeicher (oder ~273 KB pro Benutzer) für die App einzukalkulieren.We recommend that you measure resource demands during development for your app and infrastructure, but the following baseline can be a starting point in planning your deployment target: If you expect your app to support 5,000 concurrent users, consider budgeting at least 1.3 GB of server memory to the app (or ~273 KB per user).

[SignalR-Konfiguration[SignalR configuration

[Blazor Server-Apps verwenden ASP.NET Core [SignalR, um mit dem Browser zu kommunizieren.[Blazor Server apps use ASP.NET Core [SignalR to communicate with the browser. [Die Hosting- und Skalierungsbedingungen von SignalR gelten für [Blazor Server-Apps.[SignalR's hosting and scaling conditions apply to [Blazor Server apps.

[Blazor funktioniert am besten, wenn WebSockets aufgrund geringerer Latenz und wegen Zuverlässigkeit und Sicherheit zum [SignalR-Transport verwendet wird.[Blazor works best when using WebSockets as the [SignalR transport due to lower latency, reliability, and security. [SignalR verwendet Long Polling, wenn WebSockets nicht verfügbar oder die App explizit für die Verwendung von Long Polling konfiguriert ist.Long Polling is used by [SignalR when WebSockets isn't available or when the app is explicitly configured to use Long Polling. Konfigurieren Sie die App bei Bereitstellung für Azure App Service in den Einstellungen für den Dienst im Azure-Portal für die Verwendung von WebSockets.When deploying to Azure App Service, configure the app to use WebSockets in the Azure portal settings for the service. Weitere Informationen zum Konfigurieren der App für Azure App Service finden Sie in den [Richtlinien für die SignalR-Veröffentlichung.For details on configuring the app for Azure App Service, see the [SignalR publishing guidelines.

Azure [SignalR ServiceAzure [SignalR Service

Sie sollten [Azure SignalR Service für [Blazor Server-Apps verwenden.We recommend using the [Azure SignalR Service for [Blazor Server apps. Der Dienst ermöglicht das Hochskalieren einer [Blazor Server-App auf eine große Anzahl gleichzeitiger [SignalR-Verbindungen.The service allows for scaling up a [Blazor Server app to a large number of concurrent [SignalR connections. Außerdem tragen die globale Reichweite und die Hochleistungsrechenzentren von [SignalR Service erheblich zur Verringerung der geografiebedingten Latenz bei.In addition, the [SignalR service's global reach and high-performance data centers significantly aid in reducing latency due to geography. So konfigurieren Sie eine App (und stellen optional Azure [SignalR Service bereit)To configure an app (and optionally provision) the Azure [SignalR Service:

  1. Aktivieren Sie die Unterstützung von persistenten Sitzungen des Diensts, damit Clients beim Vorabrendering an denselben Server umgeleitet werden.Enable the service to support sticky sessions, where clients are redirected back to the same server when prerendering. Legen Sie die ServerStickyMode-Option oder den Konfigurationswert auf Required fest.Set the ServerStickyMode option or configuration value to Required. In der Regel erstellt eine App die Konfiguration mithilfe von einem der folgenden Ansätze:Typically, an app creates the configuration using one of the following approaches:

    • Startup.ConfigureServices:Startup.ConfigureServices:

      services.AddSignalR().AddAzureSignalR(options =>
      {
          options.ServerStickyMode = 
              Microsoft.Azure.[SignalR.ServerStickyMode.Required;
      });
      
    • Konfiguration (verwenden Sie einen der folgenden Ansätze):Configuration (use one of the following approaches):

      • appsettings.json:appsettings.json:

        "Azure:[SignalR:ServerStickyMode": "Required"
        
      • Konfiguration > Anwendungseinstellungen des App-Diensts im Azure-Portal (Name: Azure:[SignalR:ServerStickyMode, Wert: Required).The app service's Configuration > Application settings in the Azure portal (Name: Azure:[SignalR:ServerStickyMode, Value: Required).

  2. Erstellen Sie ein Veröffentlichungsprofil für Azure-Apps in Visual Studio für die [Blazor Server-App.Create an Azure Apps publish profile in Visual Studio for the [Blazor Server app.

  3. Fügen Sie dem Profil die Azure [SignalR Service-Abhängigkeit hinzu.Add the Azure [SignalR Service dependency to the profile. Wenn das Azure-Abonnement nicht über eine bereits vorhandene Azure [SignalR Service-Instanz verfügt, die der App zugewiesen werden soll, wählen Sie Neue Azure [SignalR Service-Instanz erstellen aus, um eine neue Dienstinstanz bereitzustellen.If the Azure subscription doesn't have a pre-existing Azure [SignalR Service instance to assign to the app, select Create a new Azure [SignalR Service instance to provision a new service instance.

  4. Veröffentlichen Sie die App in Azure.Publish the app to Azure.

IISIIS

Aktivieren Sie bei Verwendung von IIS Folgendes:When using IIS, enable:

KubernetesKubernetes

Erstellen Sie eine Eingangsdefinition mithilfe der folgenden Kubernetes-Anmerkungen für persistente Sitzungen:Create an ingress definition with the following Kubernetes annotations for sticky sessions:

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 mit NginxLinux with Nginx

Damit [SignalR WebSockets ordnungsgemäß funktioniert, sollten Sie sich vergewissern, dass die Header Upgrade und Connection des Proxys auf die folgenden Werte festgelegt sind und dass $connection_upgrade einem der folgenden Werte zugeordnet ist:For [SignalR WebSockets to function properly, confirm that the proxy's Upgrade and Connection headers are set to the following values and that $connection_upgrade is mapped to either:

  • Der Standardwert für den UpgradeheaderThe Upgrade header value by default.
  • close, wenn der Upgradeheader fehlt oder leer istclose when the Upgrade header is missing or empty.
http {
    map $http_upgrade $connection_upgrade {
        default Upgrade;
        ''      close;
    }

    server {
        listen      80;
        server_name example.com *.example.com
        location / {
            proxy_pass         http://localhost:5000;
            proxy_http_version 1.1;
            proxy_set_header   Upgrade $http_upgrade;
            proxy_set_header   Connection $connection_upgrade;
            proxy_set_header   Host $host;
            proxy_cache_bypass $http_upgrade;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
        }
    }
}

Weitere Informationen finden Sie in den folgenden Artikeln:For more information, see the following articles:

Linux mit ApacheLinux with Apache

Konfigurieren Sie ProxyPass für den HTTP- und WebSockets-Datenverkehr, um eine [Blazor-App hinter Apache unter Linux zu hosten.To host a [Blazor app behind Apache on Linux, configure ProxyPass for HTTP and WebSockets traffic.

Im folgenden Beispiel:In the following example:

  • Der Kestrel-Server wird auf dem Hostcomputer ausgeführt.Kestrel server is running on the host machine.
  • Die App lauscht an Port 5000 auf Datenverkehr.The app listens for traffic on port 5000.
ProxyRequests       On
ProxyPreserveHost   On
ProxyPassMatch      ^/_blazor/(.*) http://localhost:5000/_blazor/$1
ProxyPass           /_blazor ws://localhost:5000/_blazor
ProxyPass           / http://localhost:5000/
ProxyPassReverse    / http://localhost:5000/

Aktivieren Sie die folgenden Module:Enable the following modules:

a2enmod   proxy
a2enmod   proxy_wstunnel

Überprüfen Sie die Browserkonsole auf WebSockets-Fehler.Check the browser console for WebSockets errors. Fehlerbeispiele:Example errors:

  • Firefox kann unter „ws://the-domain-name.tld/_blazor?id=XXX“ keine Verbindung mit dem Server herstellen.Firefox can't establish a connection to the server at ws://the-domain-name.tld/_blazor?id=XXX.
  • Fehler: "Failed to start the transport 'WebSockets'" (Beim Starten des Transports „Websockets“ ist ein Fehler aufgetreten): Fehler: "There was an error with the transport." (Beim Transport ist ein Fehler aufgetreten.)Error: Failed to start the transport 'WebSockets': Error: There was an error with the transport.
  • Fehler: "Failed to start the transport 'LongPolling'" (Beim Starten des Transports „LongPolling“ ist ein Fehler aufgetreten): "TypeError: this.transport is undefined" (TypeError: Dieser Transport ist nicht definiert)Error: Failed to start the transport 'LongPolling': TypeError: this.transport is undefined
  • Fehler: "Unable to connect to the server with any of the available transports." (Es kann mit keinem der verfügbaren Transporte eine Verbindung mit dem Server hergestellt werden.)Error: Unable to connect to the server with any of the available transports. "WebSockets failed" (WebSockets-Fehler)WebSockets failed
  • Fehler: "Cannot send data if the connection is not in the 'Connected' State." (Es können keine Daten gesendet werden, wenn die Verbindung nicht den Zustand „Verbunden“ aufweist.)Error: Cannot send data if the connection is not in the 'Connected' State.

Weitere Informationen finden Sie in der Apache-Dokumentation.For more information, see the Apache documentation.

Messen der NetzwerklatenzMeasure network latency

Mit JS-Interop kann die Netzwerklatenz gemessen werden, wie im folgenden Beispiel veranschaulicht:JS interop can be used to measure network latency, as the following example demonstrates:

@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 OnInitializedAsync()
    {
        startTime = DateTime.UtcNow;
        var _ = await JS.InvokeAsync<string>("toString");
        latency = DateTime.UtcNow - startTime;
    }
}

Für eine sinnvolle Benutzeroberfläche empfehlen wir eine dauerhafte Latenz von höchstens 250 ms.For a reasonable UI experience, we recommend a sustained UI latency of 250ms or less.