Share via


Überblick und Behandeln von Ereignissen im Zusammenhang mit der Verbindungslebensdauer in SignalR

Warnung

Diese Dokumentation gilt nicht für die neueste Version von SignalR. Sehen Sie sich ASP.NET Core SignalR an.

Dieser Artikel bietet eine Übersicht über die SignalR-Verbindungs-, Wiederverbindungs- und Trennungsereignisse, die Sie behandeln können, sowie über Timeout- und Keepalive-Einstellungen, die Sie konfigurieren können.

In diesem Artikel wird davon ausgegangen, dass Sie bereits über kenntnisse von SignalR- und Verbindungslebensdauerereignissen verfügen. Eine Einführung in SignalR finden Sie unter Einführung in SignalR. Listen mit Verbindungslebensdauerereignissen finden Sie in den folgenden Ressourcen:

In diesem Thema verwendete Softwareversionen

Frühere Versionen dieses Themas

Informationen zu früheren Versionen von SignalR finden Sie unter Ältere Versionen von SignalR.

Fragen und Kommentare

Bitte hinterlassen Sie Feedback dazu, wie Ihnen dieses Tutorial gefallen hat und was wir in den Kommentaren unten auf der Seite verbessern könnten. Wenn Sie Fragen haben, die nicht direkt mit dem Tutorial zusammenhängen, können Sie diese im ASP.NET SignalR-Forum oder StackOverflow.com posten.

Überblick

Dieser Artikel enthält folgende Abschnitte:

Links zu API-Referenzthemen beziehen sich auf die .NET 4.5-Version der API. Wenn Sie .NET 4 verwenden, lesen Sie die .NET 4-Version der API-Themen.

Terminologie und Szenarien für die Verbindungslebensdauer

Der OnReconnected Ereignishandler in einem SignalR Hub kann für einen bestimmten Client direkt nach OnConnected , aber nicht danach OnDisconnected ausgeführt werden. Der Grund, warum Sie eine Erneute Verbindung ohne Trennung haben können, ist, dass es mehrere Möglichkeiten gibt, wie das Wort "Verbindung" in SignalR verwendet wird.

SignalR-Verbindungen, Transportverbindungen und physische Verbindungen

In diesem Artikel wird zwischen SignalR-Verbindungen, Transportverbindungen und physischen Verbindungen unterschieden:

  • SignalR-Verbindung bezieht sich auf eine logische Beziehung zwischen einem Client und einer Server-URL, die von der SignalR-API verwaltet und durch eine Verbindungs-ID eindeutig identifiziert wird. Die Daten zu dieser Beziehung werden von SignalR verwaltet und zum Herstellen einer Transportverbindung verwendet. Die Beziehung endet, und SignalR entsorgt die Daten, wenn der Client die Stop -Methode aufruft oder ein Timeoutlimit erreicht wird, während SignalR versucht, eine verlorene Transportverbindung wiederherzustellen.
  • Transportverbindung bezieht sich auf eine logische Beziehung zwischen einem Client und einem Server, die von einer der vier Transport-APIs verwaltet wird: WebSockets, vom Server gesendete Ereignisse, forever frame oder long polling. SignalR verwendet die Transport-API, um eine Transportverbindung zu erstellen, und die Transport-API hängt vom Vorhandensein einer physischen Netzwerkverbindung ab, um die Transportverbindung zu erstellen. Die Transportverbindung endet, wenn SignalR sie beendet oder wenn die Transport-API erkennt, dass die physische Verbindung unterbrochen ist.
  • Physische Verbindung bezieht sich auf die physischen Netzwerkverbindungen - Kabel, Drahtlose Signale, Router usw. – die die Kommunikation zwischen einem Clientcomputer und einem Servercomputer erleichtern. Die physische Verbindung muss vorhanden sein, um eine Transportverbindung herzustellen, und eine Transportverbindung muss hergestellt werden, um eine SignalR-Verbindung herzustellen. Das Unterbrechen der physischen Verbindung beendet jedoch nicht immer sofort die Transportverbindung oder die SignalR-Verbindung, wie weiter unten in diesem Thema erläutert wird.

Im folgenden Diagramm wird die SignalR-Verbindung durch die Hubs-API- und persistentConnection-API SignalR-Schicht dargestellt, die Transportverbindung wird durch die Transportebene dargestellt, und die physische Verbindung wird durch die Zeilen zwischen dem Server und den Clients dargestellt.

SignalR-Architekturdiagramm

Wenn Sie die Start -Methode in einem SignalR-Client aufrufen, stellen Sie SignalR-Clientcode mit allen Informationen bereit, die zum Herstellen einer physischen Verbindung mit einem Server benötigt werden. SignalR-Clientcode verwendet diese Informationen, um eine HTTP-Anforderung zu stellen und eine physische Verbindung herzustellen, die eine der vier Transportmethoden verwendet. Wenn die Transportverbindung fehlschlägt oder der Server ausfällt, wird die SignalR-Verbindung nicht sofort beendet, da der Client weiterhin über die Informationen verfügt, die er benötigt, um automatisch eine neue Transportverbindung mit derselben SignalR-URL herzustellen. In diesem Szenario ist kein Eingriff der Benutzeranwendung beteiligt, und wenn der SignalR-Clientcode eine neue Transportverbindung herstellt, wird keine neue SignalR-Verbindung gestartet. Die Kontinuität der SignalR-Verbindung spiegelt sich darin wider, dass sich die Verbindungs-ID, die beim Aufrufen der Start Methode erstellt wird, nicht ändert.

Der OnReconnected Ereignishandler auf dem Hub wird ausgeführt, wenn eine Transportverbindung nach dem Verlust automatisch wiederhergestellt wird. Der OnDisconnected Ereignishandler wird am Ende einer SignalR-Verbindung ausgeführt. Eine SignalR-Verbindung kann auf eine der folgenden Arten enden:

  • Wenn der Client die Stop -Methode aufruft, wird eine Stoppmeldung an den Server gesendet, und sowohl Client als auch Server beenden die SignalR-Verbindung sofort.
  • Nachdem die Verbindung zwischen Client und Server verloren gegangen ist, versucht der Client, die Verbindung wiederherzustellen, und der Server wartet, bis der Client die Verbindung wieder herstellt. Wenn die Verbindungsversuche nicht erfolgreich sind und das Timeout für die Trennung endet, beenden Client und Server die SignalR-Verbindung. Der Client versucht nicht mehr, eine Verbindung herzustellen, und der Server veräußert seine Darstellung der SignalR-Verbindung.
  • Wenn der Client nicht mehr ausgeführt wird, ohne die Stop Methode aufrufen zu können, wartet der Server, bis der Client die Verbindung wieder herstellt, und beendet dann die SignalR-Verbindung nach dem Timeout der Verbindung.
  • Wenn der Server nicht mehr ausgeführt wird, versucht der Client, die Verbindung wiederherzustellen (die Transportverbindung erneut zu erstellen) und beendet dann die SignalR-Verbindung nach dem Timeout der Verbindung.

Wenn keine Verbindungsprobleme auftreten und die Benutzeranwendung die SignalR-Verbindung durch Aufrufen der Stop Methode beendet, beginnen und enden die SignalR-Verbindung und die Transportverbindung ungefähr zur gleichen Zeit. In den folgenden Abschnitten werden die anderen Szenarien ausführlicher beschrieben.

Szenarien für die Transporttrennung

Physische Verbindungen sind möglicherweise langsam oder es kann zu Verbindungsunterbrechungen kommen. Abhängig von Faktoren wie der Länge der Unterbrechung kann die Transportverbindung unterbrochen werden. SignalR versucht dann, die Transportverbindung erneut herzustellen. Manchmal erkennt die Transportverbindungs-API die Unterbrechung und löscht die Transportverbindung, und SignalR stellt sofort fest, dass die Verbindung verloren geht. In anderen Szenarien wird weder der Transportverbindungs-API noch SignalR sofort bewusst, dass die Konnektivität verloren gegangen ist. Für alle Transporte mit Ausnahme der langen Abrufe verwendet der SignalR-Client eine Funktion namens keepalive , um den Verlust der Konnektivität zu überprüfen, den die Transport-API nicht erkennen kann. Informationen zu langen Abrufverbindungen finden Sie weiter unten in diesem Thema unter Timeout- und Keepalive-Einstellungen .

Wenn eine Verbindung inaktiv ist, sendet der Server regelmäßig ein Keepalive-Paket an den Client. Ab dem Datum, an dem dieser Artikel geschrieben wird, ist die Standardhäufigkeit alle 10 Sekunden. Durch das Lauschen auf diese Pakete können Clients feststellen, ob ein Verbindungsproblem vorliegt. Wenn ein Keepalive-Paket nicht empfangen wird, wenn erwartet wird, geht der Client nach kurzer Zeit davon aus, dass Verbindungsprobleme wie Langsamkeit oder Unterbrechungen vorliegen. Wenn keepalive nach längerer Zeit immer noch nicht empfangen wird, geht der Client davon aus, dass die Verbindung gelöscht wurde, und er beginnt mit dem Versuch, die Verbindung wiederherzustellen.

Das folgende Diagramm veranschaulicht die Client- und Serverereignisse, die in einem typischen Szenario ausgelöst werden, wenn Probleme mit der physischen Verbindung auftreten, die von der Transport-API nicht sofort erkannt werden. Das Diagramm gilt für die folgenden Umstände:

  • Der Transport ist WebSockets, Forever Frame oder vom Server gesendete Ereignisse.
  • Bei der physischen Netzwerkverbindung gibt es unterschiedliche Unterbrechungen.
  • Die Transport-API wird von den Unterbrechungen nicht bewusst, sodass SignalR auf die Keepalive-Funktionalität angewiesen ist, um sie zu erkennen.

Transporttrennungen

Wenn der Client in den Wiederverbindungsmodus wechselt, aber keine Transportverbindung innerhalb des Timeoutlimits für die Verbindung herstellen kann, beendet der Server die SignalR-Verbindung. In diesem Fall führt der Server die -Methode des Hubs OnDisconnected aus und stellt eine Verbindungsnachricht in die Warteschlange, die an den Client gesendet werden soll, falls der Client später eine Verbindung herstellen kann. Wenn der Client dann eine erneute Verbindung durchführt, empfängt er den Befehl disconnect und ruft die Stop -Methode auf. In diesem Szenario wird nicht ausgeführt, OnReconnected wenn der Client die Verbindung wieder hergestellt hat, und OnDisconnected wird nicht ausgeführt, wenn der Client aufruft Stop. Das folgende Diagramm veranschaulicht dieses Szenario.

Transportunterbrechungen – Servertimeout

Die SignalR-Verbindungslebensdauerereignisse, die auf dem Client ausgelöst werden können, sind die folgenden:

  • ConnectionSlow Clientereignis.

    Wird ausgelöst, wenn ein voreingestellter Anteil des Keepalive-Timeoutzeitraums seit dem Empfang der letzten Nachricht oder des letzten Keepalive-Pings verstrichen ist. Der standardmäßige Warnzeitraum für keepalive Timeouts beträgt 2/3 des Keepalive-Timeouts. Das Keepalive-Timeout beträgt 20 Sekunden, sodass die Warnung bei etwa 13 Sekunden auftritt.

    Standardmäßig sendet der Server keepalive Pings alle 10 Sekunden, und der Client sucht etwa alle 2 Sekunden auf Keepalive-Pings (ein Drittel des Unterschieds zwischen dem Wert für das keepalive Timeout und dem Wert der Keepalive-Timeoutwarnung).

    Wenn die Transport-API eine Trennung erkennt, wird SignalR möglicherweise über die Trennung informiert, bevor der Warnzeitraum für das keepalive Timeout verstreicht. In diesem Fall wird das ConnectionSlow Ereignis nicht ausgelöst, und SignalR wird direkt an das Reconnecting Ereignis gesendet.

  • Reconnecting Clientereignis.

    Wird ausgelöst, wenn (a) die Transport-API erkennt, dass die Verbindung verloren geht, oder (b) der Keepalive Timeoutzeitraum seit dem Empfang der letzten Nachricht oder des keepaliven Pings verstrichen ist. Der SignalR-Clientcode beginnt mit dem Versuch, die Verbindung wiederherzustellen. Sie können dieses Ereignis behandeln, wenn Ihre Anwendung eine Aktion ausführen soll, wenn eine Transportverbindung verloren geht. Der standardmäßige Keepalive-Timeoutzeitraum beträgt derzeit 20 Sekunden.

    Wenn Ihr Clientcode versucht, eine Hub-Methode aufzurufen, während sich SignalR im Verbindungsmodus befindet, versucht SignalR, den Befehl zu senden. In den meisten Fällen werden solche Versuche fehlschlagen, aber unter bestimmten Umständen können sie erfolgreich sein. Für die vom Server gesendeten Ereignisse, forever frame und long polling transports verwendet SignalR zwei Kommunikationskanäle, einen, den der Client zum Senden von Nachrichten und einen zum Empfangen von Nachrichten verwendet. Der für den Empfang verwendete Kanal ist der dauerhaft geöffnete Kanal, der geschlossen wird, wenn die physische Verbindung unterbrochen wird. Der für das Senden verwendete Kanal bleibt verfügbar. Wenn also die physische Konnektivität wiederhergestellt wird, kann ein Methodenaufruf vom Client an den Server erfolgreich sein, bevor der Empfangskanal wiederhergestellt wird. Der Rückgabewert wird erst empfangen, wenn SignalR den für den Empfang verwendeten Kanal erneut öffnet.

  • Reconnected Clientereignis.

    Wird ausgelöst, wenn die Transportverbindung wiederhergestellt wird. Der OnReconnected Ereignishandler im Hub wird ausgeführt.

  • Closed Clientereignis (disconnected Ereignis in JavaScript).

    Wird ausgelöst, wenn das Timeout der Verbindung abläuft, während der SignalR-Clientcode versucht, nach dem Verlust der Transportverbindung die Verbindung wiederherzustellen. Das Standardtimeout für die Verbindung beträgt 30 Sekunden. (Dieses Ereignis wird auch ausgelöst, wenn die Verbindung beendet wird, da die Stop Methode aufgerufen wird.)

Unterbrechungen der Transportverbindung, die von der Transport-API nicht erkannt werden und den Empfang von Keepalive-Pings vom Server nicht länger verzögern als der Warnzeitraum für das keepalive Timeout, führen möglicherweise nicht dazu, dass keine Ereignisse für die Verbindungslebensdauer ausgelöst werden.

Einige Netzwerkumgebungen schließen absichtlich Verbindungen im Leerlauf, und eine andere Funktion der Keepalive-Pakete besteht darin, dies zu verhindern, indem sie diese Netzwerke darüber informieren, dass eine SignalR-Verbindung verwendet wird. In extremen Fällen reicht die Standardhäufigkeit von Keepalive-Pings möglicherweise nicht aus, um geschlossene Verbindungen zu verhindern. In diesem Fall können Sie Keepalive-Pings konfigurieren, die häufiger gesendet werden sollen. Weitere Informationen finden Sie weiter unten in diesem Thema unter Timeout- und Keepalive-Einstellungen .

Hinweis

Wichtig: Die hier beschriebene Ereignissequenz ist nicht garantiert. SignalR unternimmt jeden Versuch, Ereignisse der Verbindungslebensdauer gemäß diesem Schema vorhersagbar auszulösen, aber es gibt viele Variationen von Netzwerkereignissen und viele Möglichkeiten, wie zugrunde liegende Kommunikationsframeworks wie Transport-APIs sie behandeln. Beispielsweise wird das Reconnected Ereignis möglicherweise nicht ausgelöst, wenn der Client die Verbindung wieder herstellt, oder der OnConnected Handler auf dem Server wird ausgeführt, wenn der Versuch, eine Verbindung herzustellen, nicht erfolgreich ist. In diesem Thema werden nur die Auswirkungen beschrieben, die normalerweise durch bestimmte typische Umstände verursacht würden.

Clienttrennungsszenarien

In einem Browserclient wird der SignalR-Clientcode, der eine SignalR-Verbindung verwaltet, im JavaScript-Kontext einer Webseite ausgeführt. Aus diesem Grund muss die SignalR-Verbindung beendet werden, wenn Sie von einer Seite zur anderen navigieren, und aus diesem Grund verfügen Sie über mehrere Verbindungen mit mehreren Verbindungs-IDs, wenn Sie eine Verbindung über mehrere Browserfenster oder Registerkarten herstellen. Wenn der Benutzer ein Browserfenster oder eine Registerkarte schließt oder zu einer neuen Seite navigiert oder die Seite aktualisiert, wird die SignalR-Verbindung sofort beendet, da der SignalR-Clientcode dieses Browserereignis für Sie verarbeitet und die Stop -Methode aufruft. In diesen Szenarien oder auf einer beliebigen Clientplattform, wenn Ihre Anwendung die Stop -Methode aufruft, wird der OnDisconnected Ereignishandler sofort auf dem Server ausgeführt, und der Client löst das Closed Ereignis aus (das Ereignis wird in JavaScript genannt disconnected ).

Wenn eine Clientanwendung oder der Computer, auf dem sie ausgeführt wird, abstürzt oder in den Ruhezustand wechselt (z. B. wenn der Benutzer den Laptop schließt), wird der Server nicht darüber informiert, was passiert ist. Soweit der Server weiß, kann der Verlust des Clients auf eine Verbindungsunterbrechung zurückzuführen sein, und der Client versucht möglicherweise, die Verbindung wiederherzustellen. Daher wartet der Server in diesen Szenarien, um dem Client die Möglichkeit zu geben, die Verbindung wieder herzustellen, und OnDisconnected wird erst ausgeführt, wenn der Zeitraum für das Trennen des Timeouts abläuft (standardmäßig etwa 30 Sekunden). Das folgende Diagramm veranschaulicht dieses Szenario.

Clientcomputerfehler

Servertrennungsszenarien

Wenn ein Server offline geht , wird er neu gestartet, schlägt fehl, die App-Domäne wird wiederverwendet usw. – Das Ergebnis ähnelt möglicherweise einer verlorenen Verbindung, oder die Transport-API und SignalR wissen möglicherweise sofort, dass der Server nicht mehr vorhanden ist, und SignalR kann versuchen, die Verbindung erneut herzustellen, ohne das ConnectionSlow Ereignis auszulösen. Wenn der Client in den Verbindungsmodus wechselt und der Server wiederhergestellt oder neu gestartet wird oder ein neuer Server online geschaltet wird, bevor das Timeout der Verbindung abläuft, stellt der Client die Verbindung mit dem wiederhergestellten oder neuen Server wieder her. In diesem Fall wird die SignalR-Verbindung auf dem Client fortgesetzt, und das Reconnected Ereignis wird ausgelöst. Auf dem ersten Server OnDisconnected wird nie ausgeführt, und auf dem neuen Server wird ausgeführt, OnReconnected obwohl OnConnected noch nie für diesen Client auf diesem Server ausgeführt wurde. (Der Effekt ist identisch, wenn der Client nach einem Neustart oder einem App-Domänenrecycling wieder eine Verbindung mit demselben Server herstellt, da er beim Neustart des Servers über keinen Speicher der vorherigen Verbindungsaktivität verfügt.) Im folgenden Diagramm wird davon ausgegangen, dass die Transport-API sofort auf den Verbindungsverlust aufmerksam wird, sodass das ConnectionSlow Ereignis nicht ausgelöst wird.

Serverfehler und erneute Verbindung

Wenn ein Server innerhalb des Timeoutzeitraums für die Verbindung nicht verfügbar ist, wird die SignalR-Verbindung beendet. In diesem Szenario wird das Closed Ereignis (disconnected in JavaScript-Clients) auf dem Client ausgelöst, aber OnDisconnected nie auf dem Server aufgerufen. Im folgenden Diagramm wird davon ausgegangen, dass die Transport-API keine Kenntnis vom Verbindungsverlust erhält, sodass sie von der SignalR-Keepalive-Funktionalität erkannt wird und das ConnectionSlow Ereignis ausgelöst wird.

Serverfehler und Timeout

Timeout- und Keepalive-Einstellungen

Die Standardwerte ConnectionTimeout, DisconnectTimeout, und KeepAlive sind für die meisten Szenarien geeignet, können jedoch geändert werden, wenn Ihre Umgebung besondere Anforderungen hat. Wenn Ihre Netzwerkumgebung beispielsweise Verbindungen schließt, die sich im Leerlauf befinden, für 5 Sekunden, müssen Sie möglicherweise den Keepalive-Wert verringern.

ConnectionTimeout

Diese Einstellung stellt die Zeit dar, die eine Transportverbindung geöffnet lässt und auf eine Antwort wartet, bevor sie geschlossen und eine neue Verbindung geöffnet wird. Der Standardwert ist 110 Sekunden.

Diese Einstellung gilt nur, wenn die Keepalive-Funktionalität deaktiviert ist, was normalerweise nur für den langen Abruftransport gilt. Das folgende Diagramm veranschaulicht die Auswirkungen dieser Einstellung auf eine lange Abruf-Transportverbindung.

Transportverbindung mit langer Abrufdauer

DisconnectTimeout

Diese Einstellung stellt die Zeit dar, die gewartet werden muss, nachdem eine Transportverbindung verloren gegangen ist, bevor das Disconnected Ereignis ausgelöst wird. Der Standardwert ist 30 Sekunden. Wenn Sie festlegen DisconnectTimeout, KeepAlive wird automatisch auf 1/3 des DisconnectTimeout Werts festgelegt.

KeepAlive

Diese Einstellung stellt die Zeit dar, die vor dem Senden eines Keepalive-Pakets über eine Verbindung im Leerlauf gewartet werden muss. Der Standardwert beträgt 10 Sekunden. Dieser Wert darf nicht mehr als 1/3 des DisconnectTimeout Werts sein.

Wenn Sie sowohl als auch DisconnectTimeoutKeepAlivefestlegen möchten, legen Sie nach DisconnectTimeoutfestKeepAlive. Andernfalls wird Ihre KeepAlive Einstellung überschrieben, wenn DisconnectTimeout automatisch auf 1/3 des Timeoutwerts festgelegt KeepAlive wird.

Wenn Sie keepalive Funktionalität deaktivieren möchten, legen Sie auf NULL fest KeepAlive . Die Keepalive-Funktion wird für den langen Abruftransport automatisch deaktiviert.

Ändern von Timeout- und Keepalive-Einstellungen

Um die Standardwerte für diese Einstellungen zu ändern, legen Sie sie in Application_Start Der Datei Global.asax fest, wie im folgenden Beispiel gezeigt. Die im Beispielcode angezeigten Werte sind mit den Standardwerten identisch.

protected void Application_Start(object sender, EventArgs e)
{
    // Make long polling connections wait a maximum of 110 seconds for a
    // response. When that time expires, trigger a timeout command and
    // make the client reconnect.
    GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(110);
    
    // Wait a maximum of 30 seconds after a transport connection is lost
    // before raising the Disconnected event to terminate the SignalR connection.
    GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(30);
    
    // For transports other than long polling, send a keepalive packet every
    // 10 seconds. 
    // This value must be no more than 1/3 of the DisconnectTimeout value.
    GlobalHost.Configuration.KeepAlive = TimeSpan.FromSeconds(10);
    
    RouteTable.Routes.MapHubs();
}

So benachrichtigen Sie den Benutzer über Trennungen

In einigen Anwendungen möchten Sie dem Benutzer möglicherweise eine Meldung anzeigen, wenn Konnektivitätsprobleme auftreten. Sie haben mehrere Möglichkeiten, wie und wann dies zu tun ist. Die folgenden Codebeispiele gelten für einen JavaScript-Client, der den generierten Proxy verwendet.

  • Behandeln Sie das connectionSlow Ereignis, um eine Nachricht anzuzeigen, sobald SignalR Von Verbindungsprobleme bekannt ist, bevor es in den Modus für die erneute Verbindung wechselt.

    $.connection.hub.connectionSlow(function() {
        notifyUserOfConnectionProblem(); // Your function to notify user.
    });
    
  • Behandeln Sie das reconnecting Ereignis, um eine Meldung anzuzeigen, wenn SignalR eine Trennung erkennt und in den Modus für die erneute Verbindung wechselt.

    $.connection.hub.reconnecting(function() {
        notifyUserOfTryingToReconnect(); // Your function to notify user.
    });
    
  • Behandeln Sie das disconnected Ereignis, um eine Meldung anzuzeigen, wenn ein Timeout beim Versuch einer erneuten Verbindung aufgetreten ist. In diesem Szenario besteht die einzige Möglichkeit, eine Verbindung mit dem Server erneut herzustellen, darin, die SignalR-Verbindung durch Aufrufen der Start -Methode neu zu starten, wodurch eine neue Verbindungs-ID erstellt wird. Im folgenden Codebeispiel wird ein Flag verwendet, um sicherzustellen, dass Sie die Benachrichtigung erst nach einem Timeout für die erneute Verbindung ausgeben, nicht nach einem normalen Ende der SignalR-Verbindung, die durch das Aufrufen der Stop -Methode verursacht wurde.

    var tryingToReconnect = false;
    
    $.connection.hub.reconnecting(function() {
        tryingToReconnect = true;
    });
    
    $.connection.hub.reconnected(function() {
        tryingToReconnect = false;
    });
    
    $.connection.hub.disconnected(function() {
        if(tryingToReconnect) {
            notifyUserOfDisconnect(); // Your function to notify user.
        }
    });
    

Kontinuierliche Wiederherstellung der Verbindung

In einigen Anwendungen möchten Sie möglicherweise eine Verbindung automatisch wieder herstellen, nachdem sie verloren gegangen ist und der Versuch, die Verbindung wiederherzustellen, ein Timeout aufgetreten ist. Dazu können Sie die Start -Methode von Ihrem Closed Ereignishandler (disconnected Ereignishandler auf JavaScript-Clients) aufrufen. Möglicherweise sollten Sie vor dem Aufruf Start einen bestimmten Zeitraum warten, um zu vermeiden, dass dies zu häufig geschieht, wenn der Server oder die physische Verbindung nicht verfügbar ist. Das folgende Codebeispiel gilt für einen JavaScript-Client, der den generierten Proxy verwendet.

$.connection.hub.disconnected(function() {
   setTimeout(function() {
       $.connection.hub.start();
   }, 5000); // Restart connection after 5 seconds.
});

Ein potenzielles Problem, das bei mobilen Clients zu beachten ist, besteht darin, dass kontinuierliche Verbindungsversuche, wenn der Server oder die physische Verbindung nicht verfügbar ist, zu unnötigem Akkuverbrauch führen können.

Trennen eines Clients im Servercode

SignalR Version 2 verfügt nicht über eine integrierte Server-API zum Trennen von Clients. Es gibt Pläne, diese Funktionalität in Zukunft hinzuzufügen. In der aktuellen SignalR-Version besteht die einfachste Möglichkeit zum Trennen eines Clients vom Server darin, eine Verbindungsmethode auf dem Client zu implementieren und diese Methode vom Server aufzurufen. Das folgende Codebeispiel zeigt eine Disconnect-Methode für einen JavaScript-Client unter Verwendung des generierten Proxys.

var myHubProxy = $.connection.myHub
myHubProxy.client.stopClient = function() {
    $.connection.hub.stop();
};

Warnung

Sicherheit: Weder diese Methode zum Trennen von Clients noch die vorgeschlagene integrierte API adressiert das Szenario von gehackten Clients, auf denen bösartigen Code ausgeführt wird, da die Clients eine erneute Verbindung herstellen oder der gehackte Code die stopClient Methode entfernen oder ändern könnte, was sie tut. Der geeignete Ort, um zustandsbehafteten DOS-Schutz (Denial-of-Service) zu implementieren, befindet sich nicht im Framework oder auf der Serverebene, sondern in der Front-End-Infrastruktur.

Erkennen des Grunds für eine Trennung

SignalR 2.1 fügt dem Serverereignis OnDisconnect eine Überladung hinzu, die angibt, ob der Client absichtlich getrennt wurde, anstatt einen Timeout zu haben. Der StopCalled Parameter ist true, wenn der Client die Verbindung explizit geschlossen hat. Wenn in JavaScript ein Serverfehler dazu geführt hat, dass der Client die Verbindung trennt, werden die Fehlerinformationen als $.connection.hub.lastErroran den Client übergeben.

C#-Servercode: stopCalled Parameter

public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)
{
    if (stopCalled)
    {
        Console.WriteLine(String.Format("Client {0} explicitly closed the connection.", Context.ConnectionId));
    }
    else
    {
        Console.WriteLine(String.Format("Client {0} timed out .", Context.ConnectionId));
    }
            
    return base.OnDisconnected(stopCalled);
}

JavaScript-Clientcode: Zugriff im lastErrordisconnect -Ereignis.

$.connection.hub.disconnected(function () {
    if ($.connection.hub.lastError) 
        { alert("Disconnected. Reason: " +  $.connection.hub.lastError.message); }
});