ASP.NET Core-Blazor-SignalR-Leitfaden

In diesem Artikel wird das Konfigurieren und Verwalten von SignalR Verbindungen in Blazor-Apps erläutert.

Allgemeine Anleitungen zur Konfiguration von ASP.NET Core SignalR finden Sie in den Artikeln im Bereich Übersicht über ASP.NET Core SignalR der Dokumentation. Informationen zum Konfigurieren von SignalR, das einer gehosteten Blazor WebAssembly-App hinzugefügt wurde, z. B. im Tutorial Verwenden von ASP.NET Core SignalR mit Blazor, oder einer eigenständigen Blazor WebAssembly-App, die SignalR verwendet, finden Sie unter Konfiguration von ASP.NET Core SignalR.

Deaktivieren der Middlewaredienste für die Komprimierung von Antworten für Hot Reload

Deaktivieren Sie die Middlewaredienste für die Komprimierung von Antworten in der Development-Umgebung, wenn Sie Hot Reload verwenden. In den folgenden Beispielen wird die vorhandene Umgebungsüberprüfung in einem Projekt verwendet, das aus einer Blazor-Projektvorlage erstellt wurde. Rufen Sie unabhängig davon, ob der Standardcode aus einer Projektvorlage verwendet wird oder nicht, immer zuerst UseResponseCompression in der Pipeline für die Anfrageverarbeitung auf.

In Program.cs einer Blazor Server-App:

if (!app.Environment.IsDevelopment())
{
    app.UseResponseCompression();
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

In Program.cs des Client-Projekts in einer gehosteten Blazor WebAssembly-Lösung:

if (app.Environment.IsDevelopment())
{
    app.UseWebAssemblyDebugging();
}
else
{
    app.UseResponseCompression();
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

Ursprungsübergreifende Aushandlung für die Authentifizierung für SignalR (Blazor WebAssembly)

So konfigurieren Sie den zugrunde liegenden SignalR-Client zum Senden von Anmeldeinformationen (z. B. cookie oder HTTP-Authentifizierungsheader):

  • Verwenden Sie SetBrowserRequestCredentials, um Include für ursprungsübergreifende fetch-Anforderungen festzulegen.

    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);
        }
    }
    
  • Wenn eine Hubverbindung erstellt wird, weisen Sie den HttpMessageHandler der Option HttpMessageHandlerFactory zu:

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

    Im vorherigen Beispiel wird die Hub-Verbindungs-URL mit der absoluten URI-Adresse auf /chathub konfiguriert. Dabei handelt es sich um den im SignalR aus dem Blazor-Tutorial in der Index-Komponente (Pages/Index.razor) verwendeten URL. Der URI kann auch über eine Zeichenfolge wie https://signalr.example.com oder über die Konfiguration festgelegt werden. Navigation ist ein eingefügter NavigationManager.

Weitere Informationen finden Sie unter Konfiguration von SignalR in ASP.NET Core.

Rendermodus (Blazor WebAssembly)

Wenn eine Blazor WebAssembly-App, die SignalR verwendet, so konfiguriert ist, dass das Prerendering auf dem Server ausgeführt wird, erfolgt dieses vor dem Herstellen der Clientverbindung mit dem Server. Weitere Informationen finden Sie in den folgenden Artikeln:

Zusätzliche Ressourcen für Blazor WebAssembly-Apps

Verwenden persistenter Sitzungen für Webfarmhosting (Blazor Server)

Als Reaktion auf die erste Clientanforderung führt die Blazor Server-App ein Prerendering aus, das den Status der Benutzeroberfläche auf dem Server festlegt. Versucht der Client, eine SignalR-Verbindung zu erstellen, muss er mit demselben Server erneut eine Verbindung herstellen. Blazor Server-Apps mit mehr als einem Back-End-Server sollten für SignalR-Verbindungen persistente Sitzungen implementieren.

Hinweis

Der folgende Fehler wird von einer App ausgelöst, die keine persistenten Sitzungen in einer Webfarm aktiviert hat:

blazor.server.js:1 Uncaught (in promise) Error: Invocation canceled due to the underlying connection being closed. (Nicht abgefangen (in Zusage) Fehler: Der Aufruf wurde abgebrochen, weil die zugrunde liegende Verbindung beendet wurde.)

Azure SignalR Service (Blazor Server)

Wir empfehlen die Verwendung von Azure SignalR Service für in Microsoft Azure gehostete Blazor Server-Apps. Der Dienst arbeitet mit dem Blazor-Hub der App zusammen, um eine Blazor Server-App für eine große Anzahl gleichzeitiger SignalR-Verbindungen hochskalieren zu können. Außerdem tragen die globale Reichweite und die Hochleistungsrechenzentren von SignalR Service erheblich zur Verringerung der geografiebedingten Latenz bei.

Bei Azure SignalR Service werden persistente Sitzungen aktiviert, indem die Option ServerStickyMode des Diensts oder dessen Konfigurationswert auf Required festgelegt wird. Weitere Informationen finden Sie unter Hosten und Bereitstellen von Blazor Server in ASP.NET Core.

Optionen für den Verbindungshandler für Blazor Server-Apps

Konfigurieren Sie die Verbindung Blazor Server mit der in der folgenden Tabelle dargestellten CircuitOptions-Klasse.

Option Standard BESCHREIBUNG
DetailedErrors false Sendet detaillierte Ausnahmemeldungen an JavaScript, wenn bei der Verbindung ein Ausnahmefehler auftritt oder wenn ein .NET-Methodenaufruf über JS-Interop eine Ausnahme verursacht.
DisconnectedCircuitMaxRetained 100 Die maximale Anzahl der getrennten Circuits, die sich gleichzeitig im Arbeitsspeicher des Servers befinden können.
DisconnectedCircuitRetentionPeriod 3 Minuten Maximale Zeitspanne, die ein getrennter Circuit im Arbeitsspeicher aufbewahrt wird, bevor er entfernt wird
JSInteropDefaultCallTimeout 1 Minute Maximale Zeitspanne, die der Server wartet, bevor der Aufruf einer asynchronen JavaScript-Funktion durch ein Timeout beendet wird
MaxBufferedUnacknowledgedRenderBatches 10 Maximale Anzahl nicht unbestätigter Renderbatches, die der Server zu einem bestimmten Zeitpunkt pro Circuit im Arbeitsspeicher aufbewahrt, um eine stabile Neuverbindung zu ermöglichen. Wenn die Obergrenze erreicht wird, generiert der Server keine neuen Renderbatches mehr, bis mindestens ein Batch vom Client bestätigt wurde.

Konfigurieren Sie die Optionen in Program.cs mit den Optionsdelegat zu AddServerSideBlazor. Im folgenden Beispiel werden die Standardoptionswerte aus der Tabelle oben zugewiesen. Vergewissern Sie sich, dass Program.cs den System-Namespace (using System;) verwendet.

In Program.cs:

builder.Services.AddServerSideBlazor(options =>
{
    options.DetailedErrors = false;
    options.DisconnectedCircuitMaxRetained = 100;
    options.DisconnectedCircuitRetentionPeriod = TimeSpan.FromMinutes(3);
    options.JSInteropDefaultCallTimeout = TimeSpan.FromMinutes(1);
    options.MaxBufferedUnacknowledgedRenderBatches = 10;
});

Verwenden Sie HubConnectionContextOptions mit AddHubOptions, um HubConnectionContext zu konfigurieren. Optionsbeschreibungen finden Sie unter SignalR-Konfiguration in ASP.NET Core. Im folgenden Beispiel werden die Standardoptionswerte zugewiesen. Vergewissern Sie sich, dass Program.cs den System-Namespace (using System;) verwendet.

In Program.cs:

builder.Services.AddServerSideBlazor()
    .AddHubOptions(options =>
    {
        options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);
        options.EnableDetailedErrors = false;
        options.HandshakeTimeout = TimeSpan.FromSeconds(15);
        options.KeepAliveInterval = TimeSpan.FromSeconds(15);
        options.MaximumParallelInvocationsPerClient = 1;
        options.MaximumReceiveMessageSize = 32 * 1024;
        options.StreamBufferCapacity = 10;
    });

Warnung

Der Standardwert von MaximumReceiveMessageSize ist 32 KB. Das Erhöhen des Werts kann das Risiko von Denial-of-Service-Angriffen (DoS) erhöhen.

Routenkonfiguration für den Hubendpunkt von Blazor (Blazor Server)

In der Program.cs-Datei rufen Blazor Server-Apps MapBlazorHub auf, um den Blazor-Hub dem Standardpfad der App zuzuordnen. Das Blazor Server-Skript (blazor.server.js) verweist automatisch auf den durch MapBlazorHub erstellten Endpunkt.

Reflektieren des Verbindungszustands auf der Benutzeroberfläche (Blazor Server)

Wenn der Client erkennt, dass keine Verbindung mehr besteht, wird dem Benutzer eine Standardbenutzeroberfläche angezeigt, während der Client versucht, eine neue Verbindung herzustellen. Wenn die Wiederherstellung der Verbindung fehlschlägt, wird dem Benutzer die Option angezeigt, es noch mal zu versuchen.

Wenn Sie die Benutzeroberfläche anpassen möchten, definieren Sie ein einzelnes Element mit einem id von components-reconnect-modal. Im folgenden Beispiel wird das Element auf der Hostseite platziert:

Pages/_Host.cshtml:

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

Hinweis

Wenn mehrere Elemente mit einem id von components-reconnect-modal von der App gerendert werden, empfängt nur das erste gerenderte Element CSS-Klassenänderungen, um das Element anzuzeigen oder auszublenden.

Fügen Sie dem Stylesheet der Website die folgenden CSS-Stile hinzu.

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

In der folgenden Tabelle werden die CSS-Klassen beschrieben, die vom Blazor-Framework auf das components-reconnect-modal-Element angewendet werden.

CSS-Klasse Bedeutung
components-reconnect-show Die Verbindung wurde getrennt. Der Client versucht, die Verbindung wiederherzustellen. Die modale Seite wird angezeigt.
components-reconnect-hide Auf dem Server wird eine aktive Verbindung wiederhergestellt. Die modale Seite wird ausgeblendet.
components-reconnect-failed Die Wiederherstellung der Verbindung ist wahrscheinlich aufgrund eines Netzwerkfehlers fehlgeschlagen. Zum erneuten Herstellen der Verbindung rufen Sie window.Blazor.reconnect() in JavaScript auf.
components-reconnect-rejected Die Wiederherstellung der Verbindung wurde abgelehnt. Der Server wurde zwar erreicht, jedoch hat dieser die Verbindung verweigert. Der Status des Benutzers auf dem Server wurde verworfen. Rufen Sie location.reload() in JavaScript auf, um die App neu zu laden. Dieser Verbindungszustand kann aus folgenden Gründen auftreten:
  • Aufgetretener Absturz auf der serverseitigen Verbindung.
  • Der Client war lange nicht verbunden, sodass der Server den Benutzerstatus verworfen hat. Instanzen der Komponenten des Benutzers werden verworfen.
  • Der Server wird neu gestartet, oder der Workerprozess der App wird wiederverwendet.

Passen Sie die Verzögerung an, bevor die Anzeige einer erneuten Verbindungsherstellung eingeblendet wird, indem Sie die transition-delay-Eigenschaft im CSS der Website für das modale Element festlegen. Im folgenden Beispiel wird die Übergangsverzögerung von 500 ms (Standard) auf 1.000 ms (1 Sekunde) festgelegt.

wwwroot/css/site.css:

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

Rendermodus (Blazor Server)

Standardmäßig rendern Blazor Server-Apps die Benutzeroberfläche auf dem Server schon vor dem Herstellen der Clientverbindung mit dem Server. Weitere Informationen finden Sie unter Taghilfsprogramm für Komponenten in ASP.NET Core.

Blazor Startup

Konfigurieren Sie den manuellen Start der SignalRPages/_Host.cshtml-LeitungBlazor Server einer Blazor-App in der Datei wwwroot/index.html (oder Blazor WebAssembly):

  • Fügen Sie im blazor.server.js- oder blazor.webassembly.js-Skript das Attribut autostart="false" dem Tag <script> hinzu.
  • Platzieren Sie ein Skript, das Blazor.start aufruft, nach dem Laden des Blazor-Skripts und innerhalb des schließenden </body>-Tags.

Wenn autostart deaktiviert ist, funktionieren alle Aspekte der App, die nicht von der Verbindung abhängen, normal. So ist beispielsweise das clientseitige Routing betriebsbereit. Aspekte, die von der Verbindung abhängen, sind jedoch erst betriebsbereit, nachdem Blazor.start aufgerufen wurde. Das App-Verhalten ist ohne eine bestehende Verbindung unvorhersehbar. Komponentenmethoden können beispielsweise nicht ausgeführt werden, solange die Verbindung getrennt ist.

Weitere Informationen einschließlich der zur Blazor-Initialisierung, wenn das Dokument bereit ist, und der Verkettung mit einer JS Promise finden Sie unter Starten von ASP.NET Core Blazor.

Konfigurieren von SignalR-Timeouts und Keep-Alive auf dem Client

Konfigurieren Sie die folgenden Werte für den Client:

  • serverTimeoutInMilliseconds: das Servertimeout in Millisekunden. Wenn dieses Timeout abläuft, ohne eine Nachricht vom Server zu erhalten, wird die Verbindung mit einer Fehlermeldung beendet. Der Standard-Timeoutwert beträgt 30 Sekunden. Das Servertimeout sollte mindestens doppelt so groß sein wie der dem Keep-Alive-Intervall zugewiesene Wert (keepAliveIntervalInMilliseconds).
  • keepAliveIntervalInMilliseconds: Standardintervall für das Pingen des Servers. Diese Einstellung ermöglicht dem Server, das Erkennen harter Verbindungsabbrüche, z. B. wenn ein Client seinen Computer vom Netzwerk trennt. Der Ping erfolgt höchstens so oft, wie der Server pingt. Wenn der Server alle fünf Sekunden pingt, weisen Sie ihm einen niedrigeren Wert als 5000 (5 Sekunden) zu. Der Standardwert ist 15 Sekunden. Das Keep-Alive-Intervall sollte kleiner oder gleich der Hälfte des Werts sein, der dem Servertimeout zugewiesen ist (serverTimeoutInMilliseconds).

Im folgenden Beispiel für Pages/_Host.cshtml (Blazor Server) oder wwwroot/index.html (Blazor WebAssembly) werden Standardwerte verwendet:

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

Der {HOSTING MODEL}-Platzhalter im vorstehenden Markup ist entweder server für eine Blazor Server-App oder webassembly für eine Blazor WebAssembly-App.

Wenn Sie eine Hubverbindung in einer Komponente erstellen, legen Sie ServerTimeout (Standardwert: 30 Sekunden), HandshakeTimeout (Standardwert: 15 Sekunden) und KeepAliveInterval (Standardwert: 15 Sekunden) für die erstellte HubConnection fest. Im folgenden Beispiel werden basierend auf der Index -Komponente in SignalR mit dem Blazor-Tutorial Standardwerte verwendet:

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

Beim Ändern der Werte für das Servertimeout (ServerTimeout) oder das Keep-Alive-Intervall (KeepAliveInterval):

  • Das Servertimeout sollte mindestens doppelt so groß sein wie der dem Keep-Alive-Intervall zugewiesene Wert.
  • Das Keep-Alive-Intervall sollte kleiner oder gleich der Hälfte des Werts sein, der dem Servertimeout zugewiesen ist.

Weitere Informationen finden Sie in den Abschnitten Globale Bereitstellung und Verbindungsfehler der folgenden Artikel:

Ändern des Handlers für die Wiederherstellung einer Verbindung (Blazor Server)

Die Verbindungsereignisse des Handlers für die Wiederherstellung einer Verbindung können geändert werden, um benutzerdefinierte Verhaltensweisen zu erzeugen, z. B. für Folgendes:

  • Benachrichtigung an einen Benutzer, wenn die Verbindung unterbrochen wird
  • Ausführen der Protokollierung (vom Client), wenn eine Verbindung besteht

Zum Ändern der Verbindungsereignisse registrieren Sie Rückrufe für die folgenden Verbindungsänderungen:

  • Unterbrochene Verbindungen verwenden onConnectionDown.
  • Hergestellte/wieder hergestellte Verbindungen verwenden onConnectionUp.

Es müssen sowohl onConnectionDown als auch onConnectionUp angegeben werden.

Pages/_Host.cshtml:

<body>
    ...

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

Automatisches Aktualisieren der Seite, wenn keine erneute Verbindung hergestellt werden kann (Blazor Server)

Beim Standardverhalten für das Erneuern von Verbindungen müssen die Benutzer*innen nach einem Fehler bei der erneuten Verbindungsherstellung eine manuelle Aktion zum Aktualisieren der Seite ausführen. Sie können jedoch auch einen benutzerdefinierten Verbindungshandler verwenden, um die Seite automatisch zu aktualisieren:

Pages/_Host.cshtml:

<body>
    ...

    <div id="reconnect-modal" style="display: none;"></div>
    <script src="_framework/blazor.server.js" autostart="false"></script>
    <script src="boot.js"></script>
</body>

wwwroot/boot.js:

(() => {
  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;
      },
    },
  });
})();

Weitere Informationen zum Start von Blazor finden Sie unter Starten von ASP.NET Core Blazor.

Anpassen von Anzahl und Intervall der Wiederholungsversuche zum erneuten Herstellen einer Verbindung (Blazor Server)

Legen Sie zum Anpassen der Anzahl und des Intervalls der Wiederholungsversuche zum erneuten Herstellen einer Verbindung die zulässige Anzahl von Wiederholungsversuchen (maxRetries) und den zulässigen Zeitraum in Millisekunden (retryIntervalMilliseconds) für jeden Versuch fest.

Pages/_Host.cshtml:

<body>
    ...

    <script src="_framework/blazor.server.js" autostart="false"></script>
    <script>
      Blazor.start({
        reconnectionOptions: {
          maxRetries: 3,
          retryIntervalMilliseconds: 2000
        }
      });
    </script>
</body>

Weitere Informationen zum Start von Blazor finden Sie unter Starten von ASP.NET Core Blazor.

Trennen der Blazor-Verbindung vom Client (Blazor Server)

Standardmäßig wird eine Blazor-Verbindung getrennt, wenn das unload-Ereignis der Seite ausgelöst wird. Um die Verbindung in anderen Szenarien auf dem Client zu trennen, rufen Sie Blazor.disconnect im entsprechenden Ereignishandler auf. Im folgenden Beispiel wird die Verbindung getrennt, wenn die Seite ausgeblendet wird (pagehide-Ereignis):

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

Weitere Informationen zum Start von Blazor finden Sie unter Starten von ASP.NET Core Blazor.

Blazor Server-Verbindungshandler

In Blazor Server kann mithilfe von Code ein Verbindungshandler definiert werden, mit dem Code für Zustandsänderungen einer Benutzerverbindung ausgeführt werden kann. Ein Verbindungshandler wird durch das Ableiten von CircuitHandler und Registrieren der Klasse im Dienstcontainer der App implementiert. Im folgenden Beispiel für einen Verbindungshandlers werden geöffnete SignalR-Verbindungen nachverfolgt.

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

Verbindungshandler werden mithilfe von DI registriert. Bereichsbezogene Instanzen werden pro Verbindungsinstanz erstellt. Mithilfe von TrackingCircuitHandler aus dem Beispiel oben wird ein Singletondienst erstellt, weil der Zustand aller Verbindungen nachverfolgt werden muss.

In Program.cs:

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

Wenn die Methoden eines benutzerdefinierten Verbindungshandlers einen Ausnahmefehler auslösen, ist dieser Ausnahmefehler für die Blazor Server-Verbindung schwerwiegend. Umschließen Sie den Code in einer oder mehreren try-catch-Anweisungen mit Fehlerbehandlung und -protokollierung, um Ausnahmen im Code oder in aufgerufenen Methoden eines Handlers zu tolerieren.

Wenn eine Verbindung beendet wird, weil ein Benutzer die Verbindung getrennt hat und das Framework den Verbindungsstatus bereinigt, gibt das Framework den DI-Bereich der Verbindung frei. Wenn der Bereich freigegeben wird, werden alle Dienste im Verbindungsbereich verworfen, die System.IDisposable implementieren. Wenn ein DI-Dienst während der Freigabe einen Ausnahmefehler auslöst, protokolliert das Framework die Ausnahme. Weitere Informationen finden Sie unter Abhängigkeitsinjektion in ASP.NET Core Blazor.

Zusätzliche Ressourcen für Blazor Server-Apps

Allgemeine Anleitungen zur Konfiguration von ASP.NET Core SignalR finden Sie in den Artikeln im Bereich Übersicht über ASP.NET Core SignalR der Dokumentation. Informationen zum Konfigurieren von SignalR, das einer gehosteten Blazor WebAssembly-App hinzugefügt wurde, z. B. im Tutorial Verwenden von ASP.NET Core SignalR mit Blazor, oder einer eigenständigen Blazor WebAssembly-App, die SignalR verwendet, finden Sie unter Konfiguration von ASP.NET Core SignalR.

Deaktivieren der Middlewaredienste für die Komprimierung von Antworten für Hot Reload

Deaktivieren Sie die Middlewaredienste für die Komprimierung von Antworten in der Development-Umgebung, wenn Sie Hot Reload verwenden. In den folgenden Beispielen wird die vorhandene Umgebungsüberprüfung in einem Projekt verwendet, das aus einer Blazor-Projektvorlage erstellt wurde. Rufen Sie unabhängig davon, ob der Standardcode aus einer Projektvorlage verwendet wird oder nicht, immer zuerst UseResponseCompression in der Pipeline für die Anfrageverarbeitung auf.

In Program.cs einer Blazor Server-App:

if (!app.Environment.IsDevelopment())
{
    app.UseResponseCompression();
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

In Program.cs des Client-Projekts in einer gehosteten Blazor WebAssembly-Lösung:

if (app.Environment.IsDevelopment())
{
    app.UseWebAssemblyDebugging();
}
else
{
    app.UseResponseCompression();
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

Ursprungsübergreifende Aushandlung für die Authentifizierung für SignalR (Blazor WebAssembly)

So konfigurieren Sie den zugrunde liegenden SignalR-Client zum Senden von Anmeldeinformationen (z. B. cookie oder HTTP-Authentifizierungsheader):

  • Verwenden Sie SetBrowserRequestCredentials, um Include für ursprungsübergreifende fetch-Anforderungen festzulegen.

    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);
        }
    }
    
  • Wenn eine Hubverbindung erstellt wird, weisen Sie den HttpMessageHandler der Option HttpMessageHandlerFactory zu:

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

    Im vorherigen Beispiel wird die Hub-Verbindungs-URL mit der absoluten URI-Adresse auf /chathub konfiguriert. Dabei handelt es sich um den im SignalR aus dem Blazor-Tutorial in der Index-Komponente (Pages/Index.razor) verwendeten URL. Der URI kann auch über eine Zeichenfolge wie https://signalr.example.com oder über die Konfiguration festgelegt werden. Navigation ist ein eingefügter NavigationManager.

Hinweis

Weitere Informationen zum Authentifizieren von Benutzer*innen für SignalR-Hubs finden Sie unter Schützen von ASP.NET Core Blazor WebAssembly.

Weitere Informationen finden Sie unter Konfiguration von SignalR in ASP.NET Core.

Rendermodus (Blazor WebAssembly)

Wenn eine Blazor WebAssembly-App, die SignalR verwendet, so konfiguriert ist, dass das Prerendering auf dem Server ausgeführt wird, erfolgt dieses vor dem Herstellen der Clientverbindung mit dem Server. Weitere Informationen finden Sie in den folgenden Artikeln:

Zusätzliche Ressourcen für Blazor WebAssembly-Apps

Verwenden persistenter Sitzungen für Webfarmhosting (Blazor Server)

Als Reaktion auf die erste Clientanforderung führt die Blazor Server-App ein Prerendering aus, das den Status der Benutzeroberfläche auf dem Server festlegt. Versucht der Client, eine SignalR-Verbindung zu erstellen, muss er mit demselben Server erneut eine Verbindung herstellen. Blazor Server-Apps mit mehr als einem Back-End-Server sollten für SignalR-Verbindungen persistente Sitzungen implementieren.

Hinweis

Der folgende Fehler wird von einer App ausgelöst, die keine persistenten Sitzungen in einer Webfarm aktiviert hat:

blazor.server.js:1 Uncaught (in promise) Error: Invocation canceled due to the underlying connection being closed. (Nicht abgefangen (in Zusage) Fehler: Der Aufruf wurde abgebrochen, weil die zugrunde liegende Verbindung beendet wurde.)

Azure SignalR Service (Blazor Server)

Wir empfehlen die Verwendung von Azure SignalR Service für in Microsoft Azure gehostete Blazor Server-Apps. Der Dienst arbeitet mit dem Blazor-Hub der App zusammen, um eine Blazor Server-App für eine große Anzahl gleichzeitiger SignalR-Verbindungen hochskalieren zu können. Außerdem tragen die globale Reichweite und die Hochleistungsrechenzentren von SignalR Service erheblich zur Verringerung der geografiebedingten Latenz bei.

Bei Azure SignalR Service werden persistente Sitzungen aktiviert, indem die Option ServerStickyMode des Diensts oder dessen Konfigurationswert auf Required festgelegt wird. Weitere Informationen finden Sie unter Hosten und Bereitstellen von Blazor Server in ASP.NET Core.

Optionen für den Verbindungshandler für Blazor Server-Apps

Konfigurieren Sie die Verbindung Blazor Server mit der in der folgenden Tabelle dargestellten CircuitOptions-Klasse.

Option Standard BESCHREIBUNG
DetailedErrors false Sendet detaillierte Ausnahmemeldungen an JavaScript, wenn bei der Verbindung ein Ausnahmefehler auftritt oder wenn ein .NET-Methodenaufruf über JS-Interop eine Ausnahme verursacht.
DisconnectedCircuitMaxRetained 100 Die maximale Anzahl der getrennten Circuits, die sich gleichzeitig im Arbeitsspeicher des Servers befinden können.
DisconnectedCircuitRetentionPeriod 3 Minuten Maximale Zeitspanne, die ein getrennter Circuit im Arbeitsspeicher aufbewahrt wird, bevor er entfernt wird
JSInteropDefaultCallTimeout 1 Minute Maximale Zeitspanne, die der Server wartet, bevor der Aufruf einer asynchronen JavaScript-Funktion durch ein Timeout beendet wird
MaxBufferedUnacknowledgedRenderBatches 10 Maximale Anzahl nicht unbestätigter Renderbatches, die der Server zu einem bestimmten Zeitpunkt pro Circuit im Arbeitsspeicher aufbewahrt, um eine stabile Neuverbindung zu ermöglichen. Wenn die Obergrenze erreicht wird, generiert der Server keine neuen Renderbatches mehr, bis mindestens ein Batch vom Client bestätigt wurde.

Konfigurieren Sie die Optionen in Program.cs mit den Optionsdelegat zu AddServerSideBlazor. Im folgenden Beispiel werden die Standardoptionswerte aus der Tabelle oben zugewiesen. Vergewissern Sie sich, dass Program.cs den System-Namespace (using System;) verwendet.

In Program.cs:

builder.Services.AddServerSideBlazor(options =>
{
    options.DetailedErrors = false;
    options.DisconnectedCircuitMaxRetained = 100;
    options.DisconnectedCircuitRetentionPeriod = TimeSpan.FromMinutes(3);
    options.JSInteropDefaultCallTimeout = TimeSpan.FromMinutes(1);
    options.MaxBufferedUnacknowledgedRenderBatches = 10;
});

Verwenden Sie HubConnectionContextOptions mit AddHubOptions, um HubConnectionContext zu konfigurieren. Optionsbeschreibungen finden Sie unter SignalR-Konfiguration in ASP.NET Core. Im folgenden Beispiel werden die Standardoptionswerte zugewiesen. Vergewissern Sie sich, dass Program.cs den System-Namespace (using System;) verwendet.

In Program.cs:

builder.Services.AddServerSideBlazor()
    .AddHubOptions(options =>
    {
        options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);
        options.EnableDetailedErrors = false;
        options.HandshakeTimeout = TimeSpan.FromSeconds(15);
        options.KeepAliveInterval = TimeSpan.FromSeconds(15);
        options.MaximumParallelInvocationsPerClient = 1;
        options.MaximumReceiveMessageSize = 32 * 1024;
        options.StreamBufferCapacity = 10;
    });

Warnung

Der Standardwert von MaximumReceiveMessageSize ist 32 KB. Das Erhöhen des Werts kann das Risiko von Denial-of-Service-Angriffen (DoS) erhöhen.

Routenkonfiguration für den Hubendpunkt von Blazor (Blazor Server)

In der Program.cs-Datei rufen Blazor Server-Apps MapBlazorHub auf, um den Blazor-Hub dem Standardpfad der App zuzuordnen. Das Blazor Server-Skript (blazor.server.js) verweist automatisch auf den durch MapBlazorHub erstellten Endpunkt.

Reflektieren des Verbindungszustands auf der Benutzeroberfläche (Blazor Server)

Wenn der Client erkennt, dass keine Verbindung mehr besteht, wird dem Benutzer eine Standardbenutzeroberfläche angezeigt, während der Client versucht, eine neue Verbindung herzustellen. Wenn die Wiederherstellung der Verbindung fehlschlägt, wird dem Benutzer die Option angezeigt, es noch mal zu versuchen.

Wenn Sie die Benutzeroberfläche anpassen möchten, definieren Sie ein einzelnes Element mit einem id von components-reconnect-modal. Im folgenden Beispiel wird das Element auf der Layoutseite platziert:

Pages/_Layout.cshtml:

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

Hinweis

Wenn mehrere Elemente mit einem id von components-reconnect-modal von der App gerendert werden, empfängt nur das erste gerenderte Element CSS-Klassenänderungen, um das Element anzuzeigen oder auszublenden.

Fügen Sie dem Stylesheet der Website die folgenden CSS-Stile hinzu.

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

In der folgenden Tabelle werden die CSS-Klassen beschrieben, die vom Blazor-Framework auf das components-reconnect-modal-Element angewendet werden.

CSS-Klasse Bedeutung
components-reconnect-show Die Verbindung wurde getrennt. Der Client versucht, die Verbindung wiederherzustellen. Die modale Seite wird angezeigt.
components-reconnect-hide Auf dem Server wird eine aktive Verbindung wiederhergestellt. Die modale Seite wird ausgeblendet.
components-reconnect-failed Die Wiederherstellung der Verbindung ist wahrscheinlich aufgrund eines Netzwerkfehlers fehlgeschlagen. Zum erneuten Herstellen der Verbindung rufen Sie window.Blazor.reconnect() in JavaScript auf.
components-reconnect-rejected Die Wiederherstellung der Verbindung wurde abgelehnt. Der Server wurde zwar erreicht, jedoch hat dieser die Verbindung verweigert. Der Status des Benutzers auf dem Server wurde verworfen. Rufen Sie location.reload() in JavaScript auf, um die App neu zu laden. Dieser Verbindungszustand kann aus folgenden Gründen auftreten:
  • Aufgetretener Absturz auf der serverseitigen Verbindung.
  • Der Client war lange nicht verbunden, sodass der Server den Benutzerstatus verworfen hat. Instanzen der Komponenten des Benutzers werden verworfen.
  • Der Server wird neu gestartet, oder der Workerprozess der App wird wiederverwendet.

Passen Sie die Verzögerung an, bevor die Anzeige einer erneuten Verbindungsherstellung eingeblendet wird, indem Sie die transition-delay-Eigenschaft im CSS der Website für das modale Element festlegen. Im folgenden Beispiel wird die Übergangsverzögerung von 500 ms (Standard) auf 1.000 ms (1 Sekunde) festgelegt.

wwwroot/css/site.css:

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

Rendermodus (Blazor Server)

Standardmäßig rendern Blazor Server-Apps die Benutzeroberfläche auf dem Server schon vor dem Herstellen der Clientverbindung mit dem Server. Weitere Informationen finden Sie unter Taghilfsprogramm für Komponenten in ASP.NET Core.

Blazor Startup

Konfigurieren Sie den manuellen Start der SignalRPages/_Layout.cshtml-LeitungBlazor Server einer Blazor-App in der Datei wwwroot/index.html (oder Blazor WebAssembly):

  • Fügen Sie im blazor.server.js- oder blazor.webassembly.js-Skript das Attribut autostart="false" dem Tag <script> hinzu.
  • Platzieren Sie ein Skript, das Blazor.start aufruft, nach dem Laden des Blazor-Skripts und innerhalb des schließenden </body>-Tags.

Wenn autostart deaktiviert ist, funktionieren alle Aspekte der App, die nicht von der Verbindung abhängen, normal. So ist beispielsweise das clientseitige Routing betriebsbereit. Aspekte, die von der Verbindung abhängen, sind jedoch erst betriebsbereit, nachdem Blazor.start aufgerufen wurde. Das App-Verhalten ist ohne eine bestehende Verbindung unvorhersehbar. Komponentenmethoden können beispielsweise nicht ausgeführt werden, solange die Verbindung getrennt ist.

Weitere Informationen einschließlich der zur Blazor-Initialisierung, wenn das Dokument bereit ist, und der Verkettung mit einer JS Promise finden Sie unter Starten von ASP.NET Core Blazor.

Konfigurieren von SignalR-Servertimeouts und Keep-Alive auf dem Client

Blazor Server-Hub

Dieser Abschnitt gilt nur für Blazor Server.

Konfigurieren Sie die folgenden Werte für die Blazor Server-Hubverbindung auf dem Client:

  • serverTimeoutInMilliseconds: das Servertimeout in Millisekunden. Wenn dieses Timeout abläuft, ohne eine Nachricht vom Server zu erhalten, wird die Verbindung mit einer Fehlermeldung beendet. Der Standard-Timeoutwert beträgt 30 Sekunden. Das Servertimeout sollte mindestens doppelt so groß sein wie der dem Keep-Alive-Intervall zugewiesene Wert (keepAliveIntervalInMilliseconds).
  • keepAliveIntervalInMilliseconds: Standardintervall für das Pingen des Servers. Diese Einstellung ermöglicht dem Server, das Erkennen harter Verbindungsabbrüche, z. B. wenn ein Client seinen Computer vom Netzwerk trennt. Der Ping erfolgt höchstens so oft, wie der Server pingt. Wenn der Server alle fünf Sekunden pingt, weisen Sie ihm einen niedrigeren Wert als 5000 (5 Sekunden) zu. Der Standardwert ist 15 Sekunden. Das Keep-Alive-Intervall sollte kleiner oder gleich der Hälfte des Werts sein, der dem Servertimeout zugewiesen ist (serverTimeoutInMilliseconds).

Im folgenden Beispiel für Pages/_Layout.cshtml (Blazor Server) oder wwwroot/index.html (Blazor WebAssembly) werden Standardwerte verwendet:

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

In Razor Komponenten erstellte Hubverbindungen

Dieser Abschnitt gilt nur für Blazor Server-Komponenten und Komponenten im Client-Projekt einer gehosteten Blazor WebAssembly-Lösung.

Wenn Sie eine Hubverbindung in einer Komponente erstellen, legen Sie ServerTimeout (Standardwert: 30 Sekunden), HandshakeTimeout (Standardwert: 15 Sekunden) und KeepAliveInterval (Standardwert: 15 Sekunden) für die erstellte HubConnection fest. Im folgenden Beispiel werden basierend auf der Index -Komponente in SignalR mit dem Blazor-Tutorial Standardwerte verwendet:

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

Beim Ändern der Werte für das Servertimeout (ServerTimeout) oder das Keep-Alive-Intervall (KeepAliveInterval):

  • Das Servertimeout sollte mindestens doppelt so groß sein wie der dem Keep-Alive-Intervall zugewiesene Wert.
  • Das Keep-Alive-Intervall sollte kleiner oder gleich der Hälfte des Werts sein, der dem Servertimeout zugewiesen ist.

Weitere Informationen finden Sie in den Abschnitten Globale Bereitstellung und Verbindungsfehler der folgenden Artikel:

Ändern des Handlers für die Wiederherstellung einer Verbindung (Blazor Server)

Die Verbindungsereignisse des Handlers für die Wiederherstellung einer Verbindung können geändert werden, um benutzerdefinierte Verhaltensweisen zu erzeugen, z. B. für Folgendes:

  • Benachrichtigung an einen Benutzer, wenn die Verbindung unterbrochen wird
  • Ausführen der Protokollierung (vom Client), wenn eine Verbindung besteht

Zum Ändern der Verbindungsereignisse registrieren Sie Rückrufe für die folgenden Verbindungsänderungen:

  • Unterbrochene Verbindungen verwenden onConnectionDown.
  • Hergestellte/wieder hergestellte Verbindungen verwenden onConnectionUp.

Es müssen sowohl onConnectionDown als auch onConnectionUp angegeben werden.

Pages/_Layout.cshtml:

<body>
    ...

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

Weitere Informationen zum Start von Blazor finden Sie unter Starten von ASP.NET Core Blazor.

Anpassen von Anzahl und Intervall der Wiederholungsversuche zum erneuten Herstellen einer Verbindung (Blazor Server)

Legen Sie zum Anpassen der Anzahl und des Intervalls der Wiederholungsversuche zum erneuten Herstellen einer Verbindung die zulässige Anzahl von Wiederholungsversuchen (maxRetries) und den zulässigen Zeitraum in Millisekunden (retryIntervalMilliseconds) für jeden Versuch fest.

Pages/_Layout.cshtml:

<body>
    ...

    <script src="_framework/blazor.server.js" autostart="false"></script>
    <script>
      Blazor.start({
        reconnectionOptions: {
          maxRetries: 3,
          retryIntervalMilliseconds: 2000
        }
      });
    </script>
</body>

Weitere Informationen zum Start von Blazor finden Sie unter Starten von ASP.NET Core Blazor.

Trennen der Blazor-Verbindung vom Client (Blazor Server)

Standardmäßig wird eine Blazor-Verbindung getrennt, wenn das unload-Ereignis der Seite ausgelöst wird. Um die Verbindung in anderen Szenarien auf dem Client zu trennen, rufen Sie Blazor.disconnect im entsprechenden Ereignishandler auf. Im folgenden Beispiel wird die Verbindung getrennt, wenn die Seite ausgeblendet wird (pagehide-Ereignis):

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

Weitere Informationen zum Start von Blazor finden Sie unter Starten von ASP.NET Core Blazor.

Blazor Server-Verbindungshandler

In Blazor Server kann mithilfe von Code ein Verbindungshandler definiert werden, mit dem Code für Zustandsänderungen einer Benutzerverbindung ausgeführt werden kann. Ein Verbindungshandler wird durch das Ableiten von CircuitHandler und Registrieren der Klasse im Dienstcontainer der App implementiert. Im folgenden Beispiel für einen Verbindungshandlers werden geöffnete SignalR-Verbindungen nachverfolgt.

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

Verbindungshandler werden mithilfe von DI registriert. Bereichsbezogene Instanzen werden pro Verbindungsinstanz erstellt. Mithilfe von TrackingCircuitHandler aus dem Beispiel oben wird ein Singletondienst erstellt, weil der Zustand aller Verbindungen nachverfolgt werden muss.

In Program.cs:

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

Wenn die Methoden eines benutzerdefinierten Verbindungshandlers einen Ausnahmefehler auslösen, ist dieser Ausnahmefehler für die Blazor Server-Verbindung schwerwiegend. Umschließen Sie den Code in einer oder mehreren try-catch-Anweisungen mit Fehlerbehandlung und -protokollierung, um Ausnahmen im Code oder in aufgerufenen Methoden eines Handlers zu tolerieren.

Wenn eine Verbindung beendet wird, weil ein Benutzer die Verbindung getrennt hat und das Framework den Verbindungsstatus bereinigt, gibt das Framework den DI-Bereich der Verbindung frei. Wenn der Bereich freigegeben wird, werden alle Dienste im Verbindungsbereich verworfen, die System.IDisposable implementieren. Wenn ein DI-Dienst während der Freigabe einen Ausnahmefehler auslöst, protokolliert das Framework die Ausnahme. Weitere Informationen finden Sie unter Abhängigkeitsinjektion in ASP.NET Core Blazor.

Zusätzliche Ressourcen für Blazor Server-Apps

Allgemeine Anleitungen zur Konfiguration von ASP.NET Core SignalR finden Sie in den Artikeln im Bereich Übersicht über ASP.NET Core SignalR der Dokumentation. Informationen zum Konfigurieren von SignalR, das einer gehosteten Blazor WebAssembly-App hinzugefügt wurde, z. B. im Tutorial Verwenden von ASP.NET Core SignalR mit Blazor, oder einer eigenständigen Blazor WebAssembly-App, die SignalR verwendet, finden Sie unter Konfiguration von ASP.NET Core SignalR.

Ursprungsübergreifende Aushandlung für die Authentifizierung für SignalR (Blazor WebAssembly)

So konfigurieren Sie den zugrunde liegenden SignalR-Client zum Senden von Anmeldeinformationen (z. B. cookie oder HTTP-Authentifizierungsheader):

  • Verwenden Sie SetBrowserRequestCredentials, um Include für ursprungsübergreifende fetch-Anforderungen festzulegen.

    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);
        }
    }
    
  • Wenn eine Hubverbindung erstellt wird, weisen Sie den HttpMessageHandler der Option HttpMessageHandlerFactory zu:

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

    Im vorherigen Beispiel wird die Hub-Verbindungs-URL mit der absoluten URI-Adresse auf /chathub konfiguriert. Dabei handelt es sich um den im SignalR aus dem Blazor-Tutorial in der Index-Komponente (Pages/Index.razor) verwendeten URL. Der URI kann auch über eine Zeichenfolge wie https://signalr.example.com oder über die Konfiguration festgelegt werden. Navigation ist ein eingefügter NavigationManager.

Hinweis

Weitere Informationen zum Authentifizieren von Benutzer*innen für SignalR-Hubs finden Sie unter Schützen von ASP.NET Core Blazor WebAssembly.

Weitere Informationen finden Sie unter Konfiguration von SignalR in ASP.NET Core.

Rendermodus (Blazor WebAssembly)

Wenn eine Blazor WebAssembly-App, die SignalR verwendet, so konfiguriert ist, dass das Prerendering auf dem Server ausgeführt wird, erfolgt dieses vor dem Herstellen der Clientverbindung mit dem Server. Weitere Informationen finden Sie in den folgenden Artikeln:

Zusätzliche Ressourcen für Blazor WebAssembly-Apps

Verwenden persistenter Sitzungen für Webfarmhosting (Blazor Server)

Als Reaktion auf die erste Clientanforderung führt die Blazor Server-App ein Prerendering aus, das den Zustand der Benutzeroberfläche auf dem Server festlegt. Versucht der Client, eine SignalR-Verbindung zu erstellen, muss er mit demselben Server erneut eine Verbindung herstellen. Blazor Server-Apps mit mehr als einem Back-End-Server sollten für SignalR-Verbindungen persistente Sitzungen implementieren.

Hinweis

Der folgende Fehler wird von einer App ausgelöst, die keine persistenten Sitzungen in einer Webfarm aktiviert hat:

blazor.server.js:1 Uncaught (in promise) Error: Invocation canceled due to the underlying connection being closed. (Nicht abgefangen (in Zusage) Fehler: Der Aufruf wurde abgebrochen, weil die zugrunde liegende Verbindung beendet wurde.)

Azure SignalR Service (Blazor Server)

Wir empfehlen die Verwendung von Azure SignalR Service für in Microsoft Azure gehostete Blazor Server-Apps. Der Dienst arbeitet mit dem Blazor-Hub der App zusammen, um eine Blazor Server-App für eine große Anzahl gleichzeitiger SignalR-Verbindungen hochskalieren zu können. Außerdem tragen die globale Reichweite und die Hochleistungsrechenzentren von SignalR Service erheblich zur Verringerung der geografiebedingten Latenz bei.

Um Unterstützung für Vorabrendern in Azure SignalR Service zu erhalten, konfigurieren Sie die App für die Verwendung von persistenten Sitzungen. Weitere Informationen finden Sie unter Hosten und Bereitstellen von Blazor Server in ASP.NET Core.

Optionen für den Verbindungshandler für Blazor Server-Apps

Konfigurieren Sie die Verbindung Blazor Server mit der in der folgenden Tabelle dargestellten CircuitOptions-Klasse.

Option Standard BESCHREIBUNG
DetailedErrors false Sendet detaillierte Ausnahmemeldungen an JavaScript, wenn bei der Verbindung ein Ausnahmefehler auftritt oder wenn ein .NET-Methodenaufruf über JS-Interop eine Ausnahme verursacht.
DisconnectedCircuitMaxRetained 100 Die maximale Anzahl der getrennten Circuits, die sich gleichzeitig im Arbeitsspeicher des Servers befinden können.
DisconnectedCircuitRetentionPeriod 3 Minuten Maximale Zeitspanne, die ein getrennter Circuit im Arbeitsspeicher aufbewahrt wird, bevor er entfernt wird
JSInteropDefaultCallTimeout 1 Minute Maximale Zeitspanne, die der Server wartet, bevor der Aufruf einer asynchronen JavaScript-Funktion durch ein Timeout beendet wird
MaxBufferedUnacknowledgedRenderBatches 10 Maximale Anzahl nicht unbestätigter Renderbatches, die der Server zu einem bestimmten Zeitpunkt pro Circuit im Arbeitsspeicher aufbewahrt, um eine stabile Neuverbindung zu ermöglichen. Wenn die Obergrenze erreicht wird, generiert der Server keine neuen Renderbatches mehr, bis mindestens ein Batch vom Client bestätigt wurde.

Konfigurieren Sie die Optionen in Startup.ConfigureServices mit den Optionsdelegat zu AddServerSideBlazor. Im folgenden Beispiel werden die Standardoptionswerte aus der Tabelle oben zugewiesen. Vergewissern Sie sich, dass Startup.cs den System-Namespace (using System;) verwendet.

Startup.ConfigureServices:

services.AddServerSideBlazor(options =>
{
    options.DetailedErrors = false;
    options.DisconnectedCircuitMaxRetained = 100;
    options.DisconnectedCircuitRetentionPeriod = TimeSpan.FromMinutes(3);
    options.JSInteropDefaultCallTimeout = TimeSpan.FromMinutes(1);
    options.MaxBufferedUnacknowledgedRenderBatches = 10;
});

Verwenden Sie HubConnectionContextOptions mit AddHubOptions, um HubConnectionContext zu konfigurieren. Optionsbeschreibungen finden Sie unter SignalR-Konfiguration in ASP.NET Core. Im folgenden Beispiel werden die Standardoptionswerte zugewiesen. Vergewissern Sie sich, dass Startup.cs den System-Namespace (using System;) verwendet.

Startup.ConfigureServices:

services.AddServerSideBlazor()
    .AddHubOptions(options =>
    {
        options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);
        options.EnableDetailedErrors = false;
        options.HandshakeTimeout = TimeSpan.FromSeconds(15);
        options.KeepAliveInterval = TimeSpan.FromSeconds(15);
        options.MaximumParallelInvocationsPerClient = 1;
        options.MaximumReceiveMessageSize = 32 * 1024;
        options.StreamBufferCapacity = 10;
    });

Warnung

Der Standardwert von MaximumReceiveMessageSize ist 32 KB. Das Erhöhen des Werts kann das Risiko von Denial-of-Service-Angriffen (DoS) erhöhen.

Routenkonfiguration für den Hubendpunkt von Blazor (Blazor Server)

In Startup.Configure rufen Blazor Server-Apps MapBlazorHub für den IEndpointRouteBuilder von UseEndpoints auf, um den Blazor-Hub dem Standardpfad der App zuzuordnen. Das Blazor Server-Skript (blazor.server.js) verweist automatisch auf den durch MapBlazorHub erstellten Endpunkt.

Reflektieren des Verbindungszustands auf der Benutzeroberfläche (Blazor Server)

Wenn der Client erkennt, dass keine Verbindung mehr besteht, wird dem Benutzer eine Standardbenutzeroberfläche angezeigt, während der Client versucht, eine neue Verbindung herzustellen. Wenn die Wiederherstellung der Verbindung fehlschlägt, wird dem Benutzer die Option angezeigt, es noch mal zu versuchen.

Wenn Sie die Benutzeroberfläche anpassen möchten, definieren Sie ein einzelnes Element mit einem id von components-reconnect-modal. Im folgenden Beispiel wird das Element auf der Hostseite platziert:

Pages/_Host.cshtml:

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

Hinweis

Wenn mehrere Elemente mit einem id von components-reconnect-modal von der App gerendert werden, empfängt nur das erste gerenderte Element CSS-Klassenänderungen, um das Element anzuzeigen oder auszublenden.

Fügen Sie dem Stylesheet der Website die folgenden CSS-Stile hinzu.

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

In der folgenden Tabelle werden die CSS-Klassen beschrieben, die vom Blazor-Framework auf das components-reconnect-modal-Element angewendet werden.

CSS-Klasse Bedeutung
components-reconnect-show Die Verbindung wurde getrennt. Der Client versucht, die Verbindung wiederherzustellen. Die modale Seite wird angezeigt.
components-reconnect-hide Auf dem Server wird eine aktive Verbindung wiederhergestellt. Die modale Seite wird ausgeblendet.
components-reconnect-failed Die Wiederherstellung der Verbindung ist wahrscheinlich aufgrund eines Netzwerkfehlers fehlgeschlagen. Zum erneuten Herstellen der Verbindung rufen Sie window.Blazor.reconnect() in JavaScript auf.
components-reconnect-rejected Die Wiederherstellung der Verbindung wurde abgelehnt. Der Server wurde zwar erreicht, jedoch hat dieser die Verbindung verweigert. Der Status des Benutzers auf dem Server wurde verworfen. Rufen Sie location.reload() in JavaScript auf, um die App neu zu laden. Dieser Verbindungszustand kann aus folgenden Gründen auftreten:
  • Aufgetretener Absturz auf der serverseitigen Verbindung.
  • Der Client war lange nicht verbunden, sodass der Server den Benutzerstatus verworfen hat. Instanzen der Komponenten des Benutzers werden verworfen.
  • Der Server wird neu gestartet, oder der Workerprozess der App wird wiederverwendet.

Passen Sie die Verzögerung an, bevor die Anzeige einer erneuten Verbindungsherstellung eingeblendet wird, indem Sie die transition-delay-Eigenschaft im CSS der Website für das modale Element festlegen. Im folgenden Beispiel wird die Übergangsverzögerung von 500 ms (Standard) auf 1.000 ms (1 Sekunde) festgelegt.

wwwroot/css/site.css:

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

Rendermodus (Blazor Server)

Standardmäßig rendern Blazor Server-Apps die Benutzeroberfläche auf dem Server schon vor dem Herstellen der Clientverbindung mit dem Server. Weitere Informationen finden Sie unter Taghilfsprogramm für Komponenten in ASP.NET Core.

Blazor Startup

Konfigurieren Sie den manuellen Start der SignalRPages/_Host.cshtml-LeitungBlazor Server einer Blazor-App in der Datei wwwroot/index.html (oder Blazor WebAssembly):

  • Fügen Sie im blazor.server.js- oder blazor.webassembly.js-Skript das Attribut autostart="false" dem Tag <script> hinzu.
  • Platzieren Sie ein Skript, das Blazor.start aufruft, nach dem Laden des Blazor-Skripts und innerhalb des schließenden </body>-Tags.

Wenn autostart deaktiviert ist, funktionieren alle Aspekte der App, die nicht von der Verbindung abhängen, normal. So ist beispielsweise das clientseitige Routing betriebsbereit. Aspekte, die von der Verbindung abhängen, sind jedoch erst betriebsbereit, nachdem Blazor.start aufgerufen wurde. Das App-Verhalten ist ohne eine bestehende Verbindung unvorhersehbar. Komponentenmethoden können beispielsweise nicht ausgeführt werden, solange die Verbindung getrennt ist.

Weitere Informationen einschließlich der zur Blazor-Initialisierung, wenn das Dokument bereit ist, und der Verkettung mit einer JS Promise finden Sie unter Starten von ASP.NET Core Blazor.

Konfigurieren von SignalR-Servertimeouts und Keep-Alive auf dem Client

Blazor Server-Hub

Dieser Abschnitt gilt nur für Blazor Server.

Konfigurieren Sie die folgenden Werte für die Blazor Server-Hubverbindung auf dem Client:

  • serverTimeoutInMilliseconds: das Servertimeout in Millisekunden. Wenn dieses Timeout abläuft, ohne eine Nachricht vom Server zu erhalten, wird die Verbindung mit einer Fehlermeldung beendet. Der Standard-Timeoutwert beträgt 30 Sekunden. Das Servertimeout sollte mindestens doppelt so groß sein wie der dem Keep-Alive-Intervall zugewiesene Wert (keepAliveIntervalInMilliseconds).
  • keepAliveIntervalInMilliseconds: Standardintervall für das Pingen des Servers. Diese Einstellung ermöglicht dem Server, das Erkennen harter Verbindungsabbrüche, z. B. wenn ein Client seinen Computer vom Netzwerk trennt. Der Ping erfolgt höchstens so oft, wie der Server pingt. Wenn der Server alle fünf Sekunden pingt, weisen Sie ihm einen niedrigeren Wert als 5000 (5 Sekunden) zu. Der Standardwert ist 15 Sekunden. Das Keep-Alive-Intervall sollte kleiner oder gleich der Hälfte des Werts sein, der dem Servertimeout zugewiesen ist (serverTimeoutInMilliseconds).

Im folgenden Beispiel für Pages/_Host.cshtml (Blazor Server) oder wwwroot/index.html (Blazor WebAssembly) werden Standardwerte verwendet:

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

In Razor Komponenten erstellte Hubverbindungen

Dieser Abschnitt gilt nur für Blazor Server-Komponenten und Komponenten im Client-Projekt einer gehosteten Blazor WebAssembly-Lösung.

Wenn Sie eine Hubverbindung in einer Komponente erstellen, legen Sie ServerTimeout (Standardwert: 30 Sekunden), HandshakeTimeout (Standardwert: 15 Sekunden) und KeepAliveInterval (Standardwert: 15 Sekunden) für die erstellte HubConnection fest. Im folgenden Beispiel werden basierend auf der Index -Komponente in SignalR mit dem Blazor-Tutorial Standardwerte verwendet:

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

Beim Ändern der Werte für das Servertimeout (ServerTimeout) oder das Keep-Alive-Intervall (KeepAliveInterval):

  • Das Servertimeout sollte mindestens doppelt so groß sein wie der dem Keep-Alive-Intervall zugewiesene Wert.
  • Das Keep-Alive-Intervall sollte kleiner oder gleich der Hälfte des Werts sein, der dem Servertimeout zugewiesen ist.

Weitere Informationen finden Sie in den Abschnitten Globale Bereitstellung und Verbindungsfehler der folgenden Artikel:

Ändern des Handlers für die Wiederherstellung einer Verbindung (Blazor Server)

Die Verbindungsereignisse des Handlers für die Wiederherstellung einer Verbindung können geändert werden, um benutzerdefinierte Verhaltensweisen zu erzeugen, z. B. für Folgendes:

  • Benachrichtigung an einen Benutzer, wenn die Verbindung unterbrochen wird
  • Ausführen der Protokollierung (vom Client), wenn eine Verbindung besteht

Zum Ändern der Verbindungsereignisse registrieren Sie Rückrufe für die folgenden Verbindungsänderungen:

  • Unterbrochene Verbindungen verwenden onConnectionDown.
  • Hergestellte/wieder hergestellte Verbindungen verwenden onConnectionUp.

Es müssen sowohl onConnectionDown als auch onConnectionUp angegeben werden.

Pages/_Host.cshtml:

<body>
    ...

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

Weitere Informationen zum Start von Blazor finden Sie unter Starten von ASP.NET Core Blazor.

Anpassen von Anzahl und Intervall der Wiederholungsversuche zum erneuten Herstellen einer Verbindung (Blazor Server)

Legen Sie zum Anpassen der Anzahl und des Intervalls der Wiederholungsversuche zum erneuten Herstellen einer Verbindung die zulässige Anzahl von Wiederholungsversuchen (maxRetries) und den zulässigen Zeitraum in Millisekunden (retryIntervalMilliseconds) für jeden Versuch fest.

Pages/_Host.cshtml:

<body>
    ...

    <script src="_framework/blazor.server.js" autostart="false"></script>
    <script>
      Blazor.start({
        reconnectionOptions: {
          maxRetries: 3,
          retryIntervalMilliseconds: 2000
        }
      });
    </script>
</body>

Weitere Informationen zum Start von Blazor finden Sie unter Starten von ASP.NET Core Blazor.

Trennen der Blazor-Verbindung vom Client (Blazor Server)

Standardmäßig wird eine Blazor-Verbindung getrennt, wenn das unload-Ereignis der Seite ausgelöst wird. Um die Verbindung in anderen Szenarien auf dem Client zu trennen, rufen Sie Blazor.disconnect im entsprechenden Ereignishandler auf. Im folgenden Beispiel wird die Verbindung getrennt, wenn die Seite ausgeblendet wird (pagehide-Ereignis):

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

Weitere Informationen zum Start von Blazor finden Sie unter Starten von ASP.NET Core Blazor.

Blazor Server-Verbindungshandler

In Blazor Server kann mithilfe von Code ein Verbindungshandler definiert werden, mit dem Code für Zustandsänderungen einer Benutzerverbindung ausgeführt werden kann. Ein Verbindungshandler wird durch das Ableiten von CircuitHandler und Registrieren der Klasse im Dienstcontainer der App implementiert. Im folgenden Beispiel für einen Verbindungshandlers werden geöffnete SignalR-Verbindungen nachverfolgt.

TrackingCircuitHandler.cs:

using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
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;
}

Verbindungshandler werden mithilfe von DI registriert. Bereichsbezogene Instanzen werden pro Verbindungsinstanz erstellt. Mithilfe von TrackingCircuitHandler aus dem Beispiel oben wird ein Singletondienst erstellt, weil der Zustand aller Verbindungen nachverfolgt werden muss.

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddSingleton<CircuitHandler, TrackingCircuitHandler>();
}

Wenn die Methoden eines benutzerdefinierten Verbindungshandlers einen Ausnahmefehler auslösen, ist dieser Ausnahmefehler für die Blazor Server-Verbindung schwerwiegend. Umschließen Sie den Code in einer oder mehreren try-catch-Anweisungen mit Fehlerbehandlung und -protokollierung, um Ausnahmen im Code oder in aufgerufenen Methoden eines Handlers zu tolerieren.

Wenn eine Verbindung beendet wird, weil ein Benutzer die Verbindung getrennt hat und das Framework den Verbindungsstatus bereinigt, gibt das Framework den DI-Bereich der Verbindung frei. Wenn der Bereich freigegeben wird, werden alle Dienste im Verbindungsbereich verworfen, die System.IDisposable implementieren. Wenn ein DI-Dienst während der Freigabe einen Ausnahmefehler auslöst, protokolliert das Framework die Ausnahme. Weitere Informationen finden Sie unter Abhängigkeitsinjektion in ASP.NET Core Blazor.

Zusätzliche Ressourcen für Blazor Server-Apps

Allgemeine Anleitungen zur Konfiguration von ASP.NET Core SignalR finden Sie in den Artikeln im Bereich Übersicht über ASP.NET Core SignalR der Dokumentation. Informationen zum Konfigurieren von SignalR, das einer gehosteten Blazor WebAssembly-App hinzugefügt wurde, z. B. im Tutorial Verwenden von ASP.NET Core SignalR mit Blazor, oder einer eigenständigen Blazor WebAssembly-App, die SignalR verwendet, finden Sie unter Konfiguration von ASP.NET Core SignalR.

Ursprungsübergreifende Aushandlung für die Authentifizierung für SignalR (Blazor WebAssembly)

So konfigurieren Sie den zugrunde liegenden SignalR-Client zum Senden von Anmeldeinformationen (z. B. cookie oder HTTP-Authentifizierungsheader):

  • Verwenden Sie SetBrowserRequestCredentials, um Include für ursprungsübergreifende fetch-Anforderungen festzulegen.

    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);
        }
    }
    
  • Wenn eine Hubverbindung erstellt wird, weisen Sie den HttpMessageHandler der Option HttpMessageHandlerFactory zu:

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

    Im vorherigen Beispiel wird die Hub-Verbindungs-URL mit der absoluten URI-Adresse auf /chathub konfiguriert. Dabei handelt es sich um den im SignalR aus dem Blazor-Tutorial in der Index-Komponente (Pages/Index.razor) verwendeten URL. Der URI kann auch über eine Zeichenfolge wie https://signalr.example.com oder über die Konfiguration festgelegt werden. Navigation ist ein eingefügter NavigationManager.

Hinweis

Weitere Informationen zum Authentifizieren von Benutzer*innen für SignalR-Hubs finden Sie unter Schützen von ASP.NET Core Blazor WebAssembly.

Weitere Informationen finden Sie unter Konfiguration von SignalR in ASP.NET Core.

Zusätzliche Ressourcen für Blazor WebAssembly-Apps

Verwenden persistenter Sitzungen für Webfarmhosting (Blazor Server)

Als Reaktion auf die erste Clientanforderung führt die Blazor Server-App ein Prerendering aus, das den Zustand der Benutzeroberfläche auf dem Server festlegt. Versucht der Client, eine SignalR-Verbindung zu erstellen, muss er mit demselben Server erneut eine Verbindung herstellen. Blazor Server-Apps mit mehr als einem Back-End-Server sollten für SignalR-Verbindungen persistente Sitzungen implementieren. Weitere Informationen finden Sie unter Hosten und Bereitstellen von Blazor Server in ASP.NET Core.

Hinweis

Der folgende Fehler wird von einer App ausgelöst, die keine persistenten Sitzungen in einer Webfarm aktiviert hat:

blazor.server.js:1 Uncaught (in promise) Error: Invocation canceled due to the underlying connection being closed. (Nicht abgefangen (in Zusage) Fehler: Der Aufruf wurde abgebrochen, weil die zugrunde liegende Verbindung beendet wurde.)

Azure SignalR Service (Blazor Server)

Wir empfehlen die Verwendung von Azure SignalR Service für in Microsoft Azure gehostete Blazor Server-Apps. Der Dienst arbeitet mit dem Blazor-Hub der App zusammen, um eine Blazor Server-App für eine große Anzahl gleichzeitiger SignalR-Verbindungen hochskalieren zu können. Außerdem tragen die globale Reichweite und die Hochleistungsrechenzentren von SignalR Service erheblich zur Verringerung der geografiebedingten Latenz bei.

Um Unterstützung für Vorabrendern in Azure SignalR Service zu erhalten, konfigurieren Sie die App für die Verwendung von persistenten Sitzungen. Weitere Informationen finden Sie unter Hosten und Bereitstellen von Blazor Server in ASP.NET Core.

Optionen für den Verbindungshandler für Blazor Server-Apps

Konfigurieren Sie die Verbindung Blazor Server mit der in der folgenden Tabelle dargestellten CircuitOptions-Klasse.

Option Standard BESCHREIBUNG
DetailedErrors false Sendet detaillierte Ausnahmemeldungen an JavaScript, wenn bei der Verbindung ein Ausnahmefehler auftritt oder wenn ein .NET-Methodenaufruf über JS-Interop eine Ausnahme verursacht.
DisconnectedCircuitMaxRetained 100 Die maximale Anzahl der getrennten Circuits, die sich gleichzeitig im Arbeitsspeicher des Servers befinden können.
DisconnectedCircuitRetentionPeriod 3 Minuten Maximale Zeitspanne, die ein getrennter Circuit im Arbeitsspeicher aufbewahrt wird, bevor er entfernt wird
JSInteropDefaultCallTimeout 1 Minute Maximale Zeitspanne, die der Server wartet, bevor der Aufruf einer asynchronen JavaScript-Funktion durch ein Timeout beendet wird
MaxBufferedUnacknowledgedRenderBatches 10 Maximale Anzahl nicht unbestätigter Renderbatches, die der Server zu einem bestimmten Zeitpunkt pro Circuit im Arbeitsspeicher aufbewahrt, um eine stabile Neuverbindung zu ermöglichen. Wenn die Obergrenze erreicht wird, generiert der Server keine neuen Renderbatches mehr, bis mindestens ein Batch vom Client bestätigt wurde.

Konfigurieren Sie die Optionen in Startup.ConfigureServices mit den Optionsdelegat zu AddServerSideBlazor. Im folgenden Beispiel werden die Standardoptionswerte aus der Tabelle oben zugewiesen. Vergewissern Sie sich, dass Startup.cs den System-Namespace (using System;) verwendet.

Startup.ConfigureServices:

services.AddServerSideBlazor(options =>
{
    options.DetailedErrors = false;
    options.DisconnectedCircuitMaxRetained = 100;
    options.DisconnectedCircuitRetentionPeriod = TimeSpan.FromMinutes(3);
    options.JSInteropDefaultCallTimeout = TimeSpan.FromMinutes(1);
    options.MaxBufferedUnacknowledgedRenderBatches = 10;
});

Verwenden Sie HubConnectionContextOptions mit AddHubOptions, um HubConnectionContext zu konfigurieren. Optionsbeschreibungen finden Sie unter SignalR-Konfiguration in ASP.NET Core. Im folgenden Beispiel werden die Standardoptionswerte zugewiesen. Vergewissern Sie sich, dass Startup.cs den System-Namespace (using System;) verwendet.

Startup.ConfigureServices:

services.AddServerSideBlazor()
    .AddHubOptions(options =>
    {
        options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);
        options.EnableDetailedErrors = false;
        options.HandshakeTimeout = TimeSpan.FromSeconds(15);
        options.KeepAliveInterval = TimeSpan.FromSeconds(15);
        options.MaximumParallelInvocationsPerClient = 1;
        options.MaximumReceiveMessageSize = 32 * 1024;
        options.StreamBufferCapacity = 10;
    });

Warnung

Der Standardwert von MaximumReceiveMessageSize ist 32 KB. Das Erhöhen des Werts kann das Risiko von Denial-of-Service-Angriffen (DoS) erhöhen.

Routenkonfiguration für den Hubendpunkt von Blazor (Blazor Server)

In Startup.Configure rufen Blazor Server-Apps MapBlazorHub für den IEndpointRouteBuilder von UseEndpoints auf, um den Blazor-Hub dem Standardpfad der App zuzuordnen. Das Blazor Server-Skript (blazor.server.js) verweist automatisch auf den durch MapBlazorHub erstellten Endpunkt.

Reflektieren des Verbindungszustands auf der Benutzeroberfläche (Blazor Server)

Wenn der Client erkennt, dass keine Verbindung mehr besteht, wird dem Benutzer eine Standardbenutzeroberfläche angezeigt, während der Client versucht, eine neue Verbindung herzustellen. Wenn die Wiederherstellung der Verbindung fehlschlägt, wird dem Benutzer die Option angezeigt, es noch mal zu versuchen.

Wenn Sie die Benutzeroberfläche anpassen möchten, definieren Sie ein einzelnes Element mit einem id von components-reconnect-modal. Im folgenden Beispiel wird das Element auf der Hostseite platziert:

Pages/_Host.cshtml:

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

Hinweis

Wenn mehrere Elemente mit einem id von components-reconnect-modal von der App gerendert werden, empfängt nur das erste gerenderte Element CSS-Klassenänderungen, um das Element anzuzeigen oder auszublenden.

Fügen Sie dem Stylesheet der Website die folgenden CSS-Stile hinzu.

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

In der folgenden Tabelle werden die CSS-Klassen beschrieben, die vom Blazor-Framework auf das components-reconnect-modal-Element angewendet werden.

CSS-Klasse Bedeutung
components-reconnect-show Die Verbindung wurde getrennt. Der Client versucht, die Verbindung wiederherzustellen. Die modale Seite wird angezeigt.
components-reconnect-hide Auf dem Server wird eine aktive Verbindung wiederhergestellt. Die modale Seite wird ausgeblendet.
components-reconnect-failed Die Wiederherstellung der Verbindung ist wahrscheinlich aufgrund eines Netzwerkfehlers fehlgeschlagen. Zum erneuten Herstellen der Verbindung rufen Sie window.Blazor.reconnect() in JavaScript auf.
components-reconnect-rejected Die Wiederherstellung der Verbindung wurde abgelehnt. Der Server wurde zwar erreicht, jedoch hat dieser die Verbindung verweigert. Der Status des Benutzers auf dem Server wurde verworfen. Rufen Sie location.reload() in JavaScript auf, um die App neu zu laden. Dieser Verbindungszustand kann aus folgenden Gründen auftreten:
  • Aufgetretener Absturz auf der serverseitigen Verbindung.
  • Der Client war lange nicht verbunden, sodass der Server den Benutzerstatus verworfen hat. Instanzen der Komponenten des Benutzers werden verworfen.
  • Der Server wird neu gestartet, oder der Workerprozess der App wird wiederverwendet.

Rendermodus (Blazor Server)

Standardmäßig rendern Blazor Server-Apps die Benutzeroberfläche auf dem Server schon vor dem Herstellen der Clientverbindung mit dem Server. Weitere Informationen finden Sie unter Taghilfsprogramm für Komponenten in ASP.NET Core.

Blazor Startup

Konfigurieren Sie den manuellen Start der SignalRPages/_Host.cshtml-LeitungBlazor Server einer Blazor-App in der Datei wwwroot/index.html (oder Blazor WebAssembly):

  • Fügen Sie im blazor.server.js- oder blazor.webassembly.js-Skript das Attribut autostart="false" dem Tag <script> hinzu.
  • Platzieren Sie ein Skript, das Blazor.start aufruft, nach dem Laden des Blazor-Skripts und innerhalb des schließenden </body>-Tags.

Wenn autostart deaktiviert ist, funktionieren alle Aspekte der App, die nicht von der Verbindung abhängen, normal. So ist beispielsweise das clientseitige Routing betriebsbereit. Aspekte, die von der Verbindung abhängen, sind jedoch erst betriebsbereit, nachdem Blazor.start aufgerufen wurde. Das App-Verhalten ist ohne eine bestehende Verbindung unvorhersehbar. Komponentenmethoden können beispielsweise nicht ausgeführt werden, solange die Verbindung getrennt ist.

Weitere Informationen einschließlich der zur Blazor-Initialisierung, wenn das Dokument bereit ist, und der Verkettung mit einer JS Promise finden Sie unter Starten von ASP.NET Core Blazor.

Konfigurieren von SignalR-Servertimeouts und Keep-Alive auf dem Client

Blazor Server-Hub

Dieser Abschnitt gilt nur für Blazor Server.

Konfigurieren Sie die folgenden Werte für die Blazor Server-Hubverbindung auf dem Client:

  • serverTimeoutInMilliseconds: das Servertimeout in Millisekunden. Wenn dieses Timeout abläuft, ohne eine Nachricht vom Server zu erhalten, wird die Verbindung mit einer Fehlermeldung beendet. Der Standard-Timeoutwert beträgt 30 Sekunden. Das Servertimeout sollte mindestens doppelt so groß sein wie der dem Keep-Alive-Intervall zugewiesene Wert (keepAliveIntervalInMilliseconds).
  • keepAliveIntervalInMilliseconds: Standardintervall für das Pingen des Servers. Diese Einstellung ermöglicht dem Server, das Erkennen harter Verbindungsabbrüche, z. B. wenn ein Client seinen Computer vom Netzwerk trennt. Der Ping erfolgt höchstens so oft, wie der Server pingt. Wenn der Server alle fünf Sekunden pingt, weisen Sie ihm einen niedrigeren Wert als 5000 (5 Sekunden) zu. Der Standardwert ist 15 Sekunden. Das Keep-Alive-Intervall sollte kleiner oder gleich der Hälfte des Werts sein, der dem Servertimeout zugewiesen ist (serverTimeoutInMilliseconds).

Im folgenden Beispiel für Pages/_Host.cshtml (Blazor Server) oder wwwroot/index.html (Blazor WebAssembly) werden Standardwerte verwendet:

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

In Razor Komponenten erstellte Hubverbindungen

Dieser Abschnitt gilt nur für Blazor Server-Komponenten und Komponenten im Client-Projekt einer gehosteten Blazor WebAssembly-Lösung.

Wenn Sie eine Hubverbindung in einer Komponente erstellen, legen Sie ServerTimeout (Standardwert: 30 Sekunden), HandshakeTimeout (Standardwert: 15 Sekunden) und KeepAliveInterval (Standardwert: 15 Sekunden) für die erstellte HubConnection fest. Im folgenden Beispiel werden basierend auf der Index -Komponente in SignalR mit dem Blazor-Tutorial Standardwerte verwendet:

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

Beim Ändern der Werte für das Servertimeout (ServerTimeout) oder das Keep-Alive-Intervall (KeepAliveInterval):

  • Das Servertimeout sollte mindestens doppelt so groß sein wie der dem Keep-Alive-Intervall zugewiesene Wert.
  • Das Keep-Alive-Intervall sollte kleiner oder gleich der Hälfte des Werts sein, der dem Servertimeout zugewiesen ist.

Weitere Informationen finden Sie in den Abschnitten Globale Bereitstellung und Verbindungsfehler der folgenden Artikel:

Ändern des Handlers für die Wiederherstellung einer Verbindung (Blazor Server)

Die Verbindungsereignisse des Handlers für die Wiederherstellung einer Verbindung können geändert werden, um benutzerdefinierte Verhaltensweisen zu erzeugen, z. B. für Folgendes:

  • Benachrichtigung an einen Benutzer, wenn die Verbindung unterbrochen wird
  • Ausführen der Protokollierung (vom Client), wenn eine Verbindung besteht

Zum Ändern der Verbindungsereignisse registrieren Sie Rückrufe für die folgenden Verbindungsänderungen:

  • Unterbrochene Verbindungen verwenden onConnectionDown.
  • Hergestellte/wieder hergestellte Verbindungen verwenden onConnectionUp.

Es müssen sowohl onConnectionDown als auch onConnectionUp angegeben werden.

Pages/_Host.cshtml:

<body>
    ...

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

Weitere Informationen zum Start von Blazor finden Sie unter Starten von ASP.NET Core Blazor.

Anpassen von Anzahl und Intervall der Wiederholungsversuche zum erneuten Herstellen einer Verbindung (Blazor Server)

Legen Sie zum Anpassen der Anzahl und des Intervalls der Wiederholungsversuche zum erneuten Herstellen einer Verbindung die zulässige Anzahl von Wiederholungsversuchen (maxRetries) und den zulässigen Zeitraum in Millisekunden (retryIntervalMilliseconds) für jeden Versuch fest.

Pages/_Host.cshtml:

<body>
    ...

    <script src="_framework/blazor.server.js" autostart="false"></script>
    <script>
      Blazor.start({
        reconnectionOptions: {
          maxRetries: 3,
          retryIntervalMilliseconds: 2000
        }
      });
    </script>
</body>

Weitere Informationen zum Start von Blazor finden Sie unter Starten von ASP.NET Core Blazor.

Blazor Server-Verbindungshandler

In Blazor Server kann mithilfe von Code ein Verbindungshandler definiert werden, mit dem Code für Zustandsänderungen einer Benutzerverbindung ausgeführt werden kann. Ein Verbindungshandler wird durch das Ableiten von CircuitHandler und Registrieren der Klasse im Dienstcontainer der App implementiert. Im folgenden Beispiel für einen Verbindungshandlers werden geöffnete SignalR-Verbindungen nachverfolgt.

TrackingCircuitHandler.cs:

using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Server.Circuits;

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

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

Verbindungshandler werden mithilfe von DI registriert. Bereichsbezogene Instanzen werden pro Verbindungsinstanz erstellt. Mithilfe von TrackingCircuitHandler aus dem Beispiel oben wird ein Singletondienst erstellt, weil der Zustand aller Verbindungen nachverfolgt werden muss.

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddSingleton<CircuitHandler, TrackingCircuitHandler>();
}

Wenn die Methoden eines benutzerdefinierten Verbindungshandlers einen Ausnahmefehler auslösen, ist dieser Ausnahmefehler für die Blazor Server-Verbindung schwerwiegend. Umschließen Sie den Code in einer oder mehreren try-catch-Anweisungen mit Fehlerbehandlung und -protokollierung, um Ausnahmen im Code oder in aufgerufenen Methoden eines Handlers zu tolerieren.

Wenn eine Verbindung beendet wird, weil ein Benutzer die Verbindung getrennt hat und das Framework den Verbindungsstatus bereinigt, gibt das Framework den DI-Bereich der Verbindung frei. Wenn der Bereich freigegeben wird, werden alle Dienste im Verbindungsbereich verworfen, die System.IDisposable implementieren. Wenn ein DI-Dienst während der Freigabe einen Ausnahmefehler auslöst, protokolliert das Framework die Ausnahme. Weitere Informationen finden Sie unter Abhängigkeitsinjektion in ASP.NET Core Blazor.

Zusätzliche Ressourcen für Blazor Server-Apps