SignalRASP.NET Core JavaScript-Client

Von Rachel Appel

Mit der ASP.NET Core SignalR JavaScript-Clientbibliothek können Entwickler serverseitigen Hubcode aufrufen.

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

Installieren des SignalR Clientpakets

Die SignalR JavaScript-Clientbibliothek wird als npm-Paket bereitgestellt. In den folgenden Abschnitten werden verschiedene Möglichkeiten zum Installieren der Clientbibliothek beschrieben.

Installieren mit npm

Führen Sie für Visual Studio die folgenden Befehle in Paket-Manager Console aus, während Sie sich im Stammordner befinden. Führen Sie für Visual Studio Code die folgenden Befehle über das integrierte Terminal aus.

npm init -y
npm install @microsoft/signalr

npm installiert den Paketinhalt im Ordner \ @microsoft\signalr\dist\browser node_modules. Erstellen Sie unter dem Ordner wwwroot \ lib einen neuen Ordner namens signalr. Kopieren Sie die dateisignalr.js in den Ordner wwwroot\lib\signalr.

Verweisen Sie im -Element auf SignalR den JavaScript-Client. <script> Beispiel:

<script src="~/lib/signalr/signalr.js"></script>

Verwenden eines Content Delivery Network (CDN)

Um die Clientbibliothek ohne die npm-Voraussetzung zu verwenden, verweisen Sie auf eine CDN gehostete Kopie der Clientbibliothek. Beispiel:

<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/3.1.7/signalr.min.js"></script>

Die Clientbibliothek ist in den folgenden CDNs verfügbar:

Installieren mit LibMan

LibMan kann verwendet werden, um bestimmte Clientbibliotheksdateien aus der CDN gehosteten Clientbibliothek zu installieren. Fügen Sie z. B. dem Projekt nur die verkminzte JavaScript-Datei hinzu. Weitere Informationen zu diesem Ansatz finden Sie unter Hinzufügen der SignalR Clientbibliothek.

Verbinden zu einem Hub

Mit dem folgenden Code wird eine Verbindung erstellt und gestartet. Beim Namen des Hubs wird die Groß-/Kleinschreibung nicht beachtet:

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging(signalR.LogLevel.Information)
    .build();

async function start() {
    try {
        await connection.start();
        console.log("SignalR Connected.");
    } catch (err) {
        console.log(err);
        setTimeout(start, 5000);
    }
};

connection.onclose(async () => {
    await start();
});

// Start the connection.
start();

Ursprungsübergreifende Verbindungen

In der Regel laden Browser Verbindungen aus derselben Domäne wie die angeforderte Seite. Es gibt jedoch Situationen, in denen eine Verbindung mit einer anderen Domäne erforderlich ist.

Wichtig

Der Clientcode muss eine absolute URL anstelle eines relative URL verwenden. Ändern Sie .withUrl("/chathub") in .withUrl("https://myappurl/chathub").

Um zu verhindern, dass eine schädliche Website vertrauliche Daten von einem anderen Standort liest, sind ursprungsübergreifende Verbindungen standardmäßig deaktiviert. Um eine ursprungsübergreifende Anforderung zuzulassen, aktivieren Sie sie in der Startup -Klasse:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SignalRChat.Hubs;

namespace SignalRChat
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddSignalR();

            services.AddCors(options =>
            {
                options.AddDefaultPolicy(builder =>
                {
                    builder.WithOrigins("https://example.com")
                        .AllowCredentials();
                });
            });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }

            app.UseStaticFiles();
            app.UseRouting();

            app.UseCors();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
                endpoints.MapHub<ChatHub>("/chathub");
            });
        }
    }
}

Aufrufen von Hubmethoden vom Client

JavaScript-Clients rufen öffentliche Methoden auf Hubs über die Invoke-Methode von HubConnectionauf. Die invoke -Methode akzeptiert Folgendes:

  • Der Name der Hubmethode.
  • Alle in der Hubmethode definierten Argumente.

Im folgenden Beispiel lautet der Methodenname auf dem Hub SendMessage . Das zweite und dritte Argument, das übergeben wird, invoke um den Argumenten und der Hubmethode user zuzuordnen: message

try {
    await connection.invoke("SendMessage", user, message);
} catch (err) {
    console.error(err);
}

Hinweis

Das Aufrufen von Hubmethoden von einem Client wird nur unterstützt, wenn der SignalR Azure-Dienst im Standardmodus verwendet wird. Weitere Informationen finden Sie unter Häufig gestellte Fragen (azure-signalr GitHub Repository).

Die invoke -Methode gibt eine JavaScript-Zusage zurück. Der Promise wird mit dem Rückgabewert (sofern vorhanden) aufgelöst, wenn die -Methode auf dem Server zurückgegeben wird. Wenn die -Methode auf dem Server einen Fehler auslöst, wird mit Promise der Fehlermeldung abgelehnt. Verwenden Sie async und oder die Methoden und , um diese Fälle zu await Promise then catch behandeln.

JavaScript-Clients können auch öffentliche Methoden für Hubs über die send-Methode von HubConnection aufrufen. Im Gegensatz zur invoke -Methode wartet die send Methode nicht auf eine Antwort vom Server. Die send -Methode gibt ein JavaScript Promise zurück. Der Promise wird aufgelöst, wenn die Nachricht an den Server gesendet wurde. Wenn beim Senden der Nachricht ein Fehler auftritt, wird mit Promise der Fehlermeldung abgelehnt. Verwenden Sie async und oder die Methoden und , um diese Fälle zu await Promise then catch behandeln.

Hinweis

Using send wartet nicht, bis der Server die Nachricht empfangen hat. Folglich ist es nicht möglich, Daten oder Fehler vom Server zurückzugeben.

Aufrufen von Clientmethoden über den Hub

Um Nachrichten vom Hub zu empfangen, definieren Sie eine Methode mithilfe der on-Methode von HubConnection .

  • Der Name der JavaScript-Clientmethode.
  • Argumente, die der Hub an die Methode übergibt.

Im folgenden Beispiel lautet der Methodenname ReceiveMessage . Die Argumentnamen sind user und message :

connection.on("ReceiveMessage", (user, message) => {
    const li = document.createElement("li");
    li.textContent = `${user}: ${message}`;
    document.getElementById("messageList").appendChild(li);
});

Der vorangehende Code in connection.on wird ausgeführt, wenn serverseitiger Code ihn mithilfe der SendAsync -Methode aufruft:

public async Task SendMessage(string user, string message)
{
    await Clients.All.SendAsync("ReceiveMessage", user, message);
}

SignalR bestimmt, welche Clientmethode aufgerufen werden soll, indem der Methodenname und die in und definierten Argumente SendAsync connection.on übereinstimmen.

Hinweis

Als bewährte Methode wird die start-Methode für nach HubConnection on aufgerufen. Dadurch wird sichergestellt, dass Ihre Handler registriert werden, bevor Nachrichten empfangen werden.

Fehlerbehandlung und Protokollierung

Verwenden Sie und mit und oder der -Methode von try , um catch async await Promise catch clientseitige Fehler zu behandeln. Verwenden Sie console.error , um Fehler in der Konsole des Browsers auszugeben:

try {
    await connection.invoke("SendMessage", user, message);
} catch (err) {
    console.error(err);
}

Richten Sie die clientseitige Protokollablaufverfolgung ein, indem Sie eine Protokollierung und einen Ereignistyp übergeben, die protokolliert werden sollen, wenn die Verbindung hergestellt wird. Nachrichten werden mit der angegebenen Protokollebene und höher protokolliert. Folgende Protokollebenen sind verfügbar:

  • signalR.LogLevel.Error: Fehlermeldungen. Protokolliert Error nur Nachrichten.
  • signalR.LogLevel.Warning: Warnmeldungen zu potenziellen Fehlern. Protokolliert Warning - und Error -Meldungen.
  • signalR.LogLevel.Information: Statusmeldungen ohne Fehler. Protokolliert Information Warning -, - und Error -Meldungen.
  • signalR.LogLevel.Trace: Ablaufverfolgungsmeldungen. Protokolliert alle Daten, einschließlich der zwischen Hub und Client übertragenen Daten.

Verwenden Sie die configureLogging-Methode in HubConnectionBuilder, um die Protokollebene zu konfigurieren. Nachrichten werden in der Browserkonsole protokolliert:

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging(signalR.LogLevel.Information)
    .build();

Erneutes Verbinden von Clients

Automatisches Wiederherstellen der Verbindung

Der JavaScript-Client für SignalR kann so konfiguriert werden, dass die Verbindung mithilfe der withAutomaticReconnect -Methode in HubConnectionBuilderautomatisch wiederhergestellt wird. Standardmäßig wird die Verbindung nicht automatisch wiederhergestellt.

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .withAutomaticReconnect()
    .build();

Ohne Parameter withAutomaticReconnect() konfiguriert den Client so, dass er 0, 2, 10 bzw. 30 Sekunden wartet, bevor jeder Versuch der erneuten Verbindung versucht wird und nach vier fehlgeschlagenen Versuchen beendet wird.

Bevor versucht wird, erneut eine Verbindung herzustellen, wechselt in HubConnection den Zustand und löst seine HubConnectionState.Reconnecting onreconnecting Rückrufe aus, anstatt in den Zustand zu übergehen Disconnected und seine Rückrufe wie eine auszulösen, ohne dass die automatische onclose HubConnection wiederhergestellte Verbindung konfiguriert ist. Dies bietet die Möglichkeit, Benutzer zu warnen, dass die Verbindung unterbrochen wurde, und Benutzeroberflächenelemente zu deaktivieren.

connection.onreconnecting(error => {
    console.assert(connection.state === signalR.HubConnectionState.Reconnecting);

    document.getElementById("messageInput").disabled = true;

    const li = document.createElement("li");
    li.textContent = `Connection lost due to error "${error}". Reconnecting.`;
    document.getElementById("messagesList").appendChild(li);
});

Wenn der Client innerhalb der ersten vier Versuche erfolgreich wieder eine Verbindung herstellen kann, wechselt wieder HubConnection in den Zustand und löst seine Connected onreconnected Rückrufe aus. Dies bietet die Möglichkeit, Benutzer darüber zu informieren, dass die Verbindung wiederhergestellt wurde.

Da die Verbindung für den Server völlig neu aussieht, wird eine neue connectionId für den onreconnected Rückruf bereitgestellt.

Warnung

Der onreconnected -Parameter des Rückrufs connectionId ist nicht definiert, wenn die zum Überspringen der HubConnection Aushandlungkonfiguriert wurde.

connection.onreconnected(connectionId => {
    console.assert(connection.state === signalR.HubConnectionState.Connected);

    document.getElementById("messageInput").disabled = false;

    const li = document.createElement("li");
    li.textContent = `Connection reestablished. Connected with connectionId "${connectionId}".`;
    document.getElementById("messagesList").appendChild(li);
});

withAutomaticReconnect() wird nicht so HubConnection konfiguriert, dass anfängliche Startfehler wiederholt werden. Daher müssen Startfehler manuell behandelt werden:

async function start() {
    try {
        await connection.start();
        console.assert(connection.state === signalR.HubConnectionState.Connected);
        console.log("SignalR Connected.");
    } catch (err) {
        console.assert(connection.state === signalR.HubConnectionState.Disconnected);
        console.log(err);
        setTimeout(() => start(), 5000);
    }
};

Wenn der Client die Verbindung innerhalb der ersten vier Versuche nicht erfolgreich wiederherstellen kann, wechselt in den Zustand und löst seine Rückrufe zum HubConnection Schließen Disconnected aus. Dies bietet die Möglichkeit, Benutzer darüber zu informieren, dass die Verbindung dauerhaft unterbrochen wurde, und die Aktualisierung der Seite zu empfehlen:

connection.onclose(error => {
    console.assert(connection.state === signalR.HubConnectionState.Disconnected);

    document.getElementById("messageInput").disabled = true;

    const li = document.createElement("li");
    li.textContent = `Connection closed due to error "${error}". Try refreshing this page to restart the connection.`;
    document.getElementById("messagesList").appendChild(li);
});

Um eine benutzerdefinierte Anzahl von Verbindungsversuchen vor dem Trennen der Verbindung zu konfigurieren oder den Zeitpunkt der Erneutverbindung zu ändern, withAutomaticReconnect akzeptiert ein Array von Zahlen, die die Verzögerung in Millisekunden darstellen, die gewartet werden soll, bevor jeder Verbindungsversuch gestartet wird.

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .withAutomaticReconnect([0, 0, 10000])
    .build();

    // .withAutomaticReconnect([0, 2000, 10000, 30000]) yields the default behavior

Im vorherigen Beispiel wird der so konfiguriert, dass sofort nach dem Verlust der Verbindung versucht wird, erneut HubConnection eine Verbindung herzustellen. Dies gilt auch für die Standardkonfiguration.

Wenn beim ersten Verbindungsversuch ein Fehler auftritt, wird der zweite Verbindungsversuch ebenfalls sofort gestartet, anstatt wie in der Standardkonfiguration zwei Sekunden zu warten.

Wenn der zweite Verbindungsversuch fehlschlägt, beginnt der dritte Verbindungsversuch in 10 Sekunden, was wiederum der Standardkonfiguration gleicht.

Das benutzerdefinierte Verhalten weicht dann erneut vom Standardverhalten ab, indem es nach dem dritten Fehler des Verbindungsversuchs beendet wird, anstatt einen weiteren Verbindungsversuch in weiteren 30 Sekunden wie in der Standardkonfiguration zu versuchen.

Wenn Sie noch mehr Kontrolle über die Zeitsteuerung und die Anzahl der automatischen Verbindungsversuche wünschen, akzeptiert ein Objekt, das die -Schnittstelle implementiert, die über eine einzelne Methode mit dem Namen withAutomaticReconnect IRetryPolicy nextRetryDelayInMilliseconds verfügt.

nextRetryDelayInMilliseconds nimmt ein einzelnes Argument mit dem Typ RetryContext an. verfügt RetryContext über drei Eigenschaften: und , previousRetryCount die jeweils , a und elapsedMilliseconds retryReason number number Error sind. Vor dem ersten Verbindungsversuch ist sowohl als auch 0 (null), und ist der Fehler, der den Verlust der previousRetryCount elapsedMilliseconds Verbindung verursacht retryReason hat. Nach jedem fehlgeschlagenen Wiederholungsversuch wird um eins erhöht, wird aktualisiert, um die zeitzuverursachen, die bisher für die Wiederherstellung der Verbindung in Millisekunden verbracht wurde, und ist der Fehler, der dazu führte, dass der letzte Verbindungsversuch fehlgeschlagen previousRetryCount elapsedMilliseconds retryReason ist.

nextRetryDelayInMilliseconds muss entweder eine Zahl zurückgeben, die die Anzahl von Millisekunden darstellt, die vor dem nächsten Verbindungsversuch gewartet werden soll, oder , wenn die null verbindung nicht mehr hergestellt werden HubConnection soll.

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .withAutomaticReconnect({
        nextRetryDelayInMilliseconds: retryContext => {
            if (retryContext.elapsedMilliseconds < 60000) {
                // If we've been reconnecting for less than 60 seconds so far,
                // wait between 0 and 10 seconds before the next reconnect attempt.
                return Math.random() * 10000;
            } else {
                // If we've been reconnecting for more than 60 seconds so far, stop reconnecting.
                return null;
            }
        }
    })
    .build();

Alternativ können Sie Code schreiben, mit dem der Client manuell wie unter Manuelles Wiederherstellen der Verbindung erneut verbunden wird.

Manuelles Wiederherstellen der Verbindung

Der folgende Code veranschaulicht einen typischen manuellen Ansatz für die wiederherzustellende Verbindung:

  1. Eine Funktion (in diesem Fall die start -Funktion) wird erstellt, um die Verbindung zu starten.
  2. Rufen Sie start die Funktion im Ereignishandler der Verbindung onclose auf.
async function start() {
    try {
        await connection.start();
        console.log("SignalR Connected.");
    } catch (err) {
        console.log(err);
        setTimeout(start, 5000);
    }
};

connection.onclose(async () => {
    await start();
});

Produktionsimplementierungen verwenden in der Regel ein exponentielles Back-Off oder wiederholen eine angegebene Anzahl von Wiederholungen.

Registerkarte "Browser im Deaktiviert"

Einige Browser verfügen über ein Feature zum Einfrieren oder ImAktiven von Registerkarten, um die Computerressourcennutzung für inaktive Registerkarten zu reduzieren. Dies kann dazu SignalR führen, dass Verbindungen geschlossen werden und zu einer unerwünschten Benutzererfahrung führen. Browser verwenden Heuristiken, um heuristisch zu herausfinden, ob eine Registerkarte in den Ruhezustand bringen soll, z. B.:

  • Wieder abspielen von Audiodaten
  • Halten einer Websperre
  • Halten einer IndexedDB Sperre
  • Verbindung mit einem USB-Gerät
  • Erfassen von Video oder Audio
  • Wird gespiegelt
  • Erfassen eines Fensters oder einer Anzeige

Hinweis

Diese Heuristiken können sich im Laufe der Zeit ändern oder sich von Browser zu Browser unterscheiden. Überprüfen Sie Ihre Supportmatrix, und finden Sie heraus, welche Methode für Ihre Szenarien am besten funktioniert.

Um zu vermeiden, dass eine App in den Ruhezustand geht, sollte die App eine der Heuristiken auslösen, die der Browser verwendet.

Das folgende Codebeispiel zeigt, wie Sie eine Websperre verwenden, um eine Registerkarte zu erhalten und einen unerwarteten Verbindungsabschluss zu vermeiden.

var lockResolver;
if (navigator && navigator.locks && navigator.locks.request) {
    const promise = new Promise((res) => {
        lockResolver = res;
    });

    navigator.locks.request('unique_lock_name', { mode: "shared" }, () => {
        return promise;
    });
}

Für das vorangehende Codebeispiel:

  • Websperren sind experimentell. Die bedingte Überprüfung bestätigt, dass der Browser Websperren unterstützt.
  • Der Promise Resolver ( ) wird gespeichert, damit die Sperre freigegeben werden kann, wenn der Ruhezustand lockResolver der Registerkarte akzeptabel ist.
  • Beim Schließen der Verbindung wird die Sperre durch Aufrufen von lockResolver() freigegeben. Wenn die Sperre wieder freigegeben wird, kann die Registerkarte in den Ruhezustand gesetzt werden.

Zusätzliche Ressourcen

Von Rachel Appel

Mit ASP.NET Core SignalR JavaScript-Clientbibliothek können Entwickler serverseitigen Hubcode aufrufen.

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

Installieren des SignalR Clientpakets

Die SignalR JavaScript-Clientbibliothek wird als npm-Paket bereitgestellt. In den folgenden Abschnitten werden verschiedene Möglichkeiten zum Installieren der Clientbibliothek beschrieben.

Installieren mit npm

Wenn Sie Visual Studio verwenden, führen Sie die folgenden Befehle in Paket-Manager Console aus, während Sie sich im Stammordner befinden. Führen Visual Studio Code die folgenden Befehle aus dem integrierten Terminal aus.

npm init -y
npm install @aspnet/signalr

npm installiert den Paketinhalt im \ @aspnet\signalr\dist\browser node_modules Ordner . Erstellen Sie unter dem Ordner wwwroot lib einen neuen Ordner \ namens signalr. Kopieren Sie signalr.js Datei in den Ordner wwwroot\lib\signalr.

Verweisen Sie SignalR im -Element auf den JavaScript-Client. <script> Beispiel:

<script src="~/lib/signalr/signalr.js"></script>

Verwenden eines Content Delivery Network (CDN)

Um die Clientbibliothek ohne npm-Voraussetzung zu verwenden, verweisen Sie auf CDN gehostete Kopie der Clientbibliothek. Beispiel:

<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/3.1.3/signalr.min.js"></script>

Die Clientbibliothek ist in den folgenden CDNs verfügbar:

Installieren mit LibMan

LibMan kann verwendet werden, um bestimmte Clientbibliotheksdateien aus der CDN gehosteten Clientbibliothek zu installieren. Fügen Sie dem Projekt z. B. nur die verminte JavaScript-Datei hinzu. Weitere Informationen zu diesem Ansatz finden Sie unter Hinzufügen der SignalR Clientbibliothek.

Verbinden zu einem Hub

Mit dem folgenden Code wird eine Verbindung erstellt und gestartet. Beim Namen des Hubs wird die Groß-/Kleinschreibung nicht beachtet.

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/chatHub")
    .configureLogging(signalR.LogLevel.Information)
    .build();

async function start() {
    try {
        await connection.start();
        console.log("connected");
    } catch (err) {
        console.log(err);
        setTimeout(() => start(), 5000);
    }
};

connection.onclose(async () => {
    await start();
});

// Start the connection.
start();

/* this is here to show an alternative to start, with a then
connection.start().then(() => console.log("connected"));
*/

/* this is here to show another alternative to start, with a catch
connection.start().catch(err => console.error(err));
*/

Ursprungsübergreifende Verbindungen

In der Regel laden Browser Verbindungen aus derselben Domäne wie die angeforderte Seite. In bestimmten Fällen ist jedoch eine Verbindung mit einer anderen Domäne erforderlich.

Um zu verhindern, dass eine schädliche Website vertrauliche Daten von einer anderen Website liest, sind ursprungsübergreifende Verbindungen standardmäßig deaktiviert. Um eine ursprungsübergreifende Anforderung zu ermöglichen, aktivieren Sie sie in der Startup -Klasse.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using SignalRChat.Hubs;

namespace SignalRChat
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddMvc();

            services.AddCors(options => options.AddPolicy("CorsPolicy", 
            builder => 
            {
                builder.AllowAnyMethod().AllowAnyHeader()
                       .WithOrigins("http://localhost:55830")
                       .AllowCredentials();
            }));

            services.AddSignalR();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseBrowserLink();
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();
            app.UseCors("CorsPolicy");
            app.UseSignalR(routes => 
            {
                routes.MapHub<ChatHub>("/chathub");
            });
            app.UseMvc();            
        }
    }
}

Aufrufen von Hubmethoden vom Client

JavaScript-Clients rufen öffentliche Methoden auf Hubs über die invoke-Methode von HubConnection auf. Die invoke -Methode akzeptiert zwei Argumente:

  • Der Name der Hubmethode. Im folgenden Beispiel ist der Methodenname auf dem Hub SendMessage .

  • Alle Argumente, die in der Hubmethode definiert sind. Im folgenden Beispiel lautet der Argumentname message . Der Beispielcode verwendet die Pfeilfunktionssyntax, die in aktuellen Versionen aller gängigen Browser unterstützt wird, mit Ausnahme Internet Explorer.

    connection.invoke("SendMessage", user, message).catch(err => console.error(err));
    

Hinweis

Das Aufrufen von Hubmethoden von einem Client wird nur unterstützt, wenn der SignalR Azure-Dienst im Standardmodus verwendet wird. Weitere Informationen finden Sie unter Häufig gestellte Fragen (azure-signalr GitHub-Repository).

Die invoke -Methode gibt eine JavaScript Promise zurück. Der Promise wird mit dem Rückgabewert (falls verfügbar) aufgelöst, wenn die -Methode auf dem Server zurückgegeben wird. Wenn die -Methode auf dem Server einen Fehler ausspricht, wird Promise mit der Fehlermeldung abgelehnt. Verwenden Sie then die Methoden und für den catch Promise selbst, um diese Fälle (oder Syntax) await zu behandeln.

Die send -Methode gibt einen JavaScript-Wert Promise zurück. Wird Promise aufgelöst, wenn die Nachricht an den Server gesendet wurde. Wenn beim Senden der Nachricht ein Fehler auftritt, wird Promise mit der Fehlermeldung abgelehnt. Verwenden Sie then die Methoden und für den catch Promise selbst, um diese Fälle (oder Syntax) await zu behandeln.

Hinweis

Die send Verwendung von wartet nicht, bis der Server die Nachricht empfangen hat. Daher ist es nicht möglich, Daten oder Fehler vom Server zurückzugeben.

Aufrufen von Clientmethoden über den Hub

Um Nachrichten vom Hub zu empfangen, definieren Sie eine Methode mithilfe der on-Methode von HubConnection .

  • Der Name der JavaScript-Clientmethode. Im folgenden Beispiel lautet der Methodenname ReceiveMessage .
  • Argumente, die der Hub an die Methode übergibt. Im folgenden Beispiel lautet der Argumentwert message .
connection.on("ReceiveMessage", (user, message) => {
    const encodedMsg = `${user} says ${message}`;
    const li = document.createElement("li");
    li.textContent = encodedMsg;
    document.getElementById("messagesList").appendChild(li);
});

Der vorangehende Code in connection.on wird ausgeführt, wenn serverseitiger Code ihn mithilfe der SendAsync -Methode aufruft.

public async Task SendMessage(string user, string message)
{
    await Clients.All.SendAsync("ReceiveMessage", user, message);
}

SignalR bestimmt, welche Clientmethode aufgerufen werden soll, indem der Methodenname und die in und definierten Argumente SendAsync connection.on übereinstimmen.

Hinweis

Als bewährte Methode wird die start-Methode für nach HubConnection on aufgerufen. Dadurch wird sichergestellt, dass Ihre Handler registriert werden, bevor Nachrichten empfangen werden.

Fehlerbehandlung und Protokollierung

Verketten Sie eine catch Methode an das Ende der start Methode, um clientseitige Fehler zu behandeln. Verwenden Sie console.error , um Fehler in der Konsole des Browsers auszugeben.

connection.start().catch(err => console.error(err));

Richten Sie die clientseitige Protokollablaufverfolgung ein, indem Sie eine Protokollierung und einen Ereignistyp übergeben, die protokolliert werden sollen, wenn die Verbindung hergestellt wird. Nachrichten werden mit der angegebenen Protokollebene und höher protokolliert. Folgende Protokollebenen sind verfügbar:

  • signalR.LogLevel.Error: Fehlermeldungen. Protokolliert Error nur Nachrichten.
  • signalR.LogLevel.Warning: Warnmeldungen zu potenziellen Fehlern. Protokolliert Warning - und Error -Meldungen.
  • signalR.LogLevel.Information: Statusmeldungen ohne Fehler. Protokolliert Information Warning - , - und Error -Nachrichten.
  • signalR.LogLevel.Trace: Ablaufverfolgungsmeldungen. Protokolliert alle Daten, einschließlich der zwischen Hub und Client übertragenen Daten.

Verwenden Sie die configureLogging-Methode in HubConnectionBuilder, um die Protokollebene zu konfigurieren. Nachrichten werden in der Browserkonsole protokolliert.

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/chatHub")
    .configureLogging(signalR.LogLevel.Information)
    .build();

Erneutes Verbinden von Clients

Manuelles Wiederherstellen der Verbindung

Warnung

Vor 3.0 stellt der JavaScript-Client für SignalR nicht automatisch eine neue Verbindung her. Sie müssen Code schreiben, der den Client manuell erneut verbindet.

Der folgende Code veranschaulicht einen typischen Ansatz für die manuelle Wiederherstellung der Verbindung:

  1. Eine Funktion (in diesem Fall die start -Funktion) wird erstellt, um die Verbindung zu starten.
  2. Rufen Sie die start Funktion im Ereignishandler der Verbindung onclose auf.
async function start() {
    try {
        await connection.start();
        console.log("connected");
    } catch (err) {
        console.log(err);
        setTimeout(() => start(), 5000);
    }
};

connection.onclose(async () => {
    await start();
});

Eine reale Implementierung würde ein exponentielles Back-Off verwenden oder eine bestimmte Anzahl von Wiederholungsversuchen durchführen, bevor sie aufgibt.

Zusätzliche Ressourcen