Freigeben über


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

Warnung

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

Dieser Artikel enthält eine Übersicht über die SignalR-Verbindung, die erneute Verbindung und die Trennungsereignisse, die Sie behandeln können, sowie Timeout- und Keepalive-Einstellungen, die Sie konfigurieren können.

In diesem Artikel wird davon ausgegangen, dass Sie bereits kenntnisse über SignalR- und Verbindungslebensdauerereignisse verfügen. Eine Einführung in SignalR finden Sie in der Einführung in SignalR. Eine Liste der Verbindungslebensdauerereignisse 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 geben Sie Feedback dazu, wie Sie diesem Lernprogramm gefallen haben und was wir in den Kommentaren unten auf der Seite verbessern könnten. Wenn Sie Fragen haben, die nicht direkt mit dem Lernprogramm zusammenhängen, können Sie sie im ASP.NET SignalR-Forum oder StackOverflow.com posten.

Übersicht

Dieser Artikel enthält folgende Abschnitte:

Links zu API-Referenzthemen sind 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 direkt nach, aber nicht nach OnConnected einem OnDisconnected bestimmten Client ausgeführt werden. Der Grund dafür, dass Sie eine erneute Verbindung ohne Verbindung haben können, besteht darin, dass es mehrere Möglichkeiten gibt, wie das Wort "Verbindung" in SignalR verwendet wird.

SignalR-Verbindungen, Transportverbindungen und physische Verbindungen

In diesem Artikel werden 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 verworfen die Daten, wenn der Client die Stop Methode aufruft oder ein Timeoutlimit erreicht ist, während SignalR versucht, eine verlorene Transportverbindung erneut herzustellen.
  • Die Transportverbindung bezieht sich auf eine logische Beziehung zwischen einem Client und einem Server, die von einer der vier Transport-APIs verwaltet wird: WebSockets, Server gesendete Ereignisse, für immer Frame oder lange Abrufe. SignalR verwendet die Transport-API zum Erstellen einer Transportverbindung, und die Transport-API hängt vom Vorhandensein einer physischen Netzwerkverbindung zum Erstellen der Transportverbindung ab. 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 Kommunikation zwischen einem Clientcomputer und einem Servercomputer erleichtern. Die physische Verbindung muss vorhanden sein, um eine Transportverbindung herzustellen, und eine Transportverbindung muss eingerichtet werden, um eine SignalR-Verbindung herzustellen. Das Unterbrechen der physischen Verbindung endet jedoch nicht immer sofort mit der Transportverbindung oder der SignalR-Verbindung, wie weiter unten in diesem Thema erläutert wird.

Im folgenden Diagramm wird die SignalR-Verbindung durch die Hubs-API und die PersistentConnection API SignalR-Ebene dargestellt, die Transportverbindung wird durch die Transportschicht dargestellt, und die physische Verbindung wird durch die Linien 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 benötigten Informationen bereit, um eine physische Verbindung mit einem Server herzustellen. SignalR-Clientcode verwendet diese Informationen, um eine HTTP-Anforderung zu erstellen und eine physische Verbindung herzustellen, die eine der vier Transportmethoden verwendet. Wenn die Transportverbindung fehlschlägt oder der Server fehlschlägt, wird die SignalR-Verbindung nicht sofort entfernt, da der Client weiterhin über die Benötigten Informationen verfügt, um automatisch eine neue Transportverbindung mit derselben SignalR-URL herzustellen. In diesem Szenario ist kein Eingreifen 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 in der Tatsache 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 wieder hergestellt 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 Stoppnachricht 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 auf die erneute Verbindung des Clients. Wenn die Versuche zum erneuten Verbinden nicht erfolgreich sind und der Timeoutzeitraum für die Verbindung getrennt wird, beenden Client und Server die SignalR-Verbindung. Der Client versucht nicht mehr, eine Erneute Verbindung herzustellen, und der Server entsorgt seine Darstellung der SignalR-Verbindung.
  • Wenn der Client nicht mehr ausgeführt wird, ohne die Methode aufrufen Stop zu können, wartet der Server, bis der Client erneut verbunden ist, und beendet dann die SignalR-Verbindung nach dem Timeoutzeitraum 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 Timeoutzeitraum 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.

Transporttrennszenarien

Physische Verbindungen können langsam sein, oder es gibt Unterbrechungen in der Verbindung. Abhängig von Faktoren wie der Länge der Unterbrechung kann die Transportverbindung verworfen werden. SignalR versucht dann, die Transportverbindung erneut herzustellen. Manchmal erkennt die Transportverbindungs-API die Unterbrechung und legt die Transportverbindung ab, und SignalR erkennt sofort, dass die Verbindung verloren geht. In anderen Szenarien wird weder die Transportverbindungs-API noch signalR sofort darüber informiert, dass die Konnektivität verloren gegangen ist. Für alle Transporte mit Ausnahme langer Abrufe verwendet der SignalR-Client eine Funktion namens Keepalive , um zu überprüfen, ob die Transport-API nicht erkannt werden kann. Informationen zu langen Abrufverbindungen finden Sie unter Timeout und Keepalive-Einstellungen weiter unten in diesem Thema.

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, beträgt die Standardhäufigkeit alle 10 Sekunden. Durch die Überwachung dieser 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 auftreten. Wenn der Keepalive nach längerer Zeit noch nicht empfangen wird, geht der Client davon aus, dass die Verbindung gelöscht wurde, und es beginnt, 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, für immer Frame- oder Server-gesendete Ereignisse.
  • Es gibt unterschiedliche Zeiträume von Unterbrechungen in der physischen Netzwerkverbindung.
  • Die Transport-API erkennt die Unterbrechungen nicht, sodass SignalR auf die Keepalive-Funktionalität angewiesen ist, um sie zu erkennen.

transport disconnections

Wenn der Client in den Modus für die erneute Verbindung wechselt, aber keine Transportverbindung innerhalb des Timeoutlimits der Verbindung trennen kann, beendet der Server die SignalR-Verbindung. In diesem Fall führt der Server die Methode des Hubs OnDisconnected aus und stellt eine verbindungstrennte Nachricht in die Warteschlange, die an den Client gesendet werden soll, falls der Client später eine Verbindung herstellen kann. Wenn der Client dann erneut eine Verbindung herstellen kann, empfängt er den Befehl zum Trennen und ruft die Stop Methode auf. In diesem Szenario OnReconnected wird beim erneuten Verbinden des Clients nicht ausgeführt und OnDisconnected nicht ausgeführt, wenn der Client aufruft Stop. Das folgende Diagramm veranschaulicht dieses Szenario.

Transportunterbrechungen – Servertimeout

Die Ereignisse der SignalR-Verbindungslebensdauer, 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 Keepalive-Pings vergangen ist. Der standardmäßige Warnzeitraum für keepalive Timeout ist 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 ungefähr alle 2 Sekunden auf Keepalive-Pings (ein Drittel des Unterschieds zwischen dem Keepalive Timeout-Wert und dem Keepalive Timeout-Warnwert).

    Wenn die Transport-API über eine Trennung informiert wird, wird SignalR möglicherweise über die Verbindung informiert, bevor der Warnzeitraum für keepalive Timeouts besteht. In diesem Fall würde das ConnectionSlow Ereignis nicht ausgelöst, und SignalR würde direkt zum Ereignis gehen Reconnecting .

  • Reconnecting Clientereignis.

    Wird ausgelöst, wenn (a) die Transport-API erkennt, dass die Verbindung verloren geht, oder (b) der Keepalive Timeout-Zeitraum seit dem Empfang der letzten Nachricht oder des Keepalive-Pings übergeben wurde. Der SignalR-Clientcode beginnt, eine erneute Verbindung herzustellen. 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 signalR sich im Modus für die erneute Verbindung 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, für immer Frame und lange Abruftransporte verwendet SignalR zwei Kommunikationskanäle, eine, die der Client zum Senden von Nachrichten und zum Empfangen von Nachrichten verwendet. Der kanal, der für den Empfang verwendet wird, ist der permanent geöffnete Kanal, und das ist der Kanal, der geschlossen wird, wenn die physische Verbindung unterbrochen wird. Der kanal, der zum Senden verwendet wird, bleibt verfügbar. Wenn also die physische Konnektivität wiederhergestellt wird, kann ein Methodenaufruf von Client zu Server erfolgreich sein, bevor der Empfangskanal erneut eingerichtet wird. Der Rückgabewert wurde erst empfangen, wenn signalR den Kanal erneut öffnet, der für den Empfang verwendet wird.

  • Reconnected Clientereignis.

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

  • Closed Clientereignis (disconnected Ereignis in JavaScript).

    Wird ausgelöst, wenn der Timeoutzeitraum für die Verbindung getrennt wird, während der SignalR-Clientcode versucht, die Verbindung erneut herzustellen, nachdem die Transportverbindung verloren geht. Das Standardmäßige Timeout für die Trennung beträgt 30 Sekunden. (Dieses Ereignis wird auch ausgelöst, wenn die Verbindung endet, weil 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 keepalive Timeouts, kann dazu führen, dass keine Verbindungslebensdauerereignisse ausgelöst werden.

Einige Netzwerkumgebungen schließen absichtlich Leerlaufverbindungen, und eine weitere Funktion der Keepalive-Pakete besteht darin, dies zu verhindern, indem diese Netzwerke darüber informiert werden, 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 so konfigurieren, dass sie häufiger gesendet werden. Weitere Informationen finden Sie unter Timeout und Keepalive-Einstellungen weiter unten in diesem Thema.

Hinweis

Wichtig: Die hier beschriebene Abfolge von Ereignissen ist nicht garantiert. SignalR versucht alle Verbindungslebensdauerereignisse auf vorhersehbare Weise gemäß diesem Schema auszulösen, aber es gibt viele Variationen von Netzwerkereignissen und viele Möglichkeiten, in denen zugrunde liegende Kommunikationsframeworks wie Transport-APIs diese behandeln. Beispielsweise wird das Reconnected Ereignis möglicherweise nicht ausgelöst, wenn der Client erneut eine Verbindung herstellt, oder der OnConnected Handler auf dem Server kann ausgeführt werden, wenn der Versuch, eine Verbindung herzustellen, nicht erfolgreich ist. In diesem Thema werden nur die Effekte beschrieben, die normalerweise durch bestimmte typische Umstände erzeugt werden.

Szenarien für die Clientverbindung

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 zu einer anderen navigieren. Deshalb haben Sie mehrere Verbindungen mit mehreren Verbindungs-IDs, wenn Sie eine Verbindung von mehreren Browserfenstern oder Registerkarten herstellen. Wenn der Benutzer ein Browserfenster oder eine Registerkarte schließt oder zu einer neuen Seite navigiert oder die Seite aktualisiert, endet die SignalR-Verbindung sofort, da der SignalR-Clientcode dieses Browserereignis für Sie verarbeitet und die Stop Methode aufruft. In diesen Szenarien oder in einer 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 benannt 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 aufgrund von Verbindungsunterbrechungen und der Client versuchen, die Verbindung erneut herzustellen. Daher wartet der Server in diesen Szenarien darauf, dem Client die Möglichkeit zu geben, die Verbindung wiederherzustellen, und OnDisconnected wird erst ausgeführt, wenn der Timeoutzeitraum für die Trennung abläuft (ca. 30 Sekunden standardmäßig). Das folgende Diagramm veranschaulicht dieses Szenario.

Clientcomputerfehler

Szenarien für die Serververbindung

Wenn ein Server offline wechselt – er startet neu, schlägt fehl, wird die App-Domäne wiederverwendet usw. – das Ergebnis kann einer verlorenen Verbindung ähneln, oder die Transport-API und SignalR wissen sofort, dass der Server nicht mehr vorhanden ist, und SignalR kann mit dem Erneuten Verbinden beginnen, ohne das ConnectionSlow Ereignis auszulösen. Wenn der Client in den Modus für die erneute Verbindung wechselt und der Server wiederhergestellt oder neu gestartet wird oder ein neuer Server online gestellt wird, bevor der Timeoutzeitraum der Verbindung getrennt wird, wird der Client erneut mit dem wiederhergestellten oder neuen Server verbunden. 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 er noch nie für diesen Client auf diesem Server ausgeführt wurde. (Der Effekt ist identisch, wenn der Client nach einem Neustart oder einer Wiederverwendung der App-Domäne erneut eine Verbindung mit demselben Server herstellt, da beim Neustart des Servers keine Speicher der vorherigen Verbindungsaktivität vorhanden ist.) Im folgenden Diagramm wird davon ausgegangen, dass die Transport-API sofort über die verlorene Verbindung informiert wird, sodass das ConnectionSlow Ereignis nicht ausgelöst wird.

Serverfehler und erneute Verbindung Wenn ein Server nicht innerhalb des Timeoutzeitraums zum Trennen verfügbar wird, endet die SignalR-Verbindung. In diesem Szenario wird das "Closed"-Ereignis (getrennt) in JavaScript-Clients auf dem Client ausgelöst, aber "OnDisconnected" wird nie auf dem Server aufgerufen. Im folgenden Diagramm wird davon ausgegangen, dass die Transport-API die verlorene Verbindung nicht erkennt, sodass sie von SignalR-Keepalive-Funktionen erkannt wird und das Ereignis "ConnectionSlow" ausgelöst wird.

Serverfehler und Timeout

Timeout- und Keepalive-Einstellungen

Die StandardConnectionTimeoutDisconnectTimeout- und KeepAlive Werte 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 für 5 Sekunden im Leerlauf befinden, müssen Sie möglicherweise den Keepalive-Wert verringern.

ConnectionTimeout

Diese Einstellung stellt die Zeitspanne dar, um eine Transportverbindung geöffnet zu lassen und auf eine Antwort zu warten, bevor sie geschlossen und eine neue Verbindung geöffnet wird. Der Standardwert beträgt 110 Sekunden.

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

Transportverbindung für lange Abrufe

DisconnectTimeout

Diese Einstellung stellt die Zeitspanne 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 der Wert automatisch auf 1/3 DisconnectTimeout festgelegt.

KeepAlive

Diese Einstellung stellt die Wartezeit dar, bevor ein Keepalive-Paket über eine Leerlaufverbindung gesendet wird. Der Standardwert beträgt 10 Sekunden. Dieser Wert darf nicht mehr als 1/3 des DisconnectTimeout Werts sein.

Wenn Sie sowohl als KeepAliveauch DisconnectTimeout nach DisconnectTimeoutdem Festlegen festlegen KeepAlive möchten. Andernfalls wird Ihre KeepAlive Einstellung überschrieben, wenn DisconnectTimeout sie automatisch auf 1/3 des Timeoutwerts festgelegt KeepAlive wird.

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

So ändern Sie Timeout- und Keepalive-Einstellungen

Wenn Sie die Standardwerte für diese Einstellungen ändern möchten, legen Sie sie in Application_Start der Datei "Global.asax " fest, wie im folgenden Beispiel gezeigt. Die im Beispielcode angezeigten Werte entsprechen den Standardwerten.

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 Die Verbindung

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 Meldung anzuzeigen, sobald SignalR Verbindungsprobleme erkannt hat, bevor sie wieder in den Verbindungsmodus wechselt.

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

    $.connection.hub.reconnecting(function() {
        notifyUserOfTryingToReconnect(); // Your function to notify user.
    });
    
  • Behandeln Sie das disconnected Ereignis, um eine Meldung anzuzeigen, wenn beim Versuch, eine erneute Verbindung herzustellen, ein Timeout aufgetreten ist. In diesem Szenario besteht die einzige Möglichkeit zum erneuten Herstellen einer Verbindung mit dem Server 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 nur nach einem timeout für die erneute Verbindung ausgeben, nicht nach einem normalen Ende der SignalR-Verbindung, die durch aufrufen der Stop Methode verursacht wird.

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

So wird's machen, wie Sie die Verbindung kontinuierlich wiederherstellen

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

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

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

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 Disconnect-Methode auf dem Client zu implementieren und diese Methode vom Server aufzurufen. Das folgende Codebeispiel zeigt eine Disconnect-Methode für einen JavaScript-Client mit dem generierten Proxy.

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 behandelt das Szenario gehackter Clients, die bösartigen Code ausführen, da die Clients eine erneute Verbindung herstellen oder der gehackte Code die stopClient Methode entfernen oder ändern kann. Der geeignete Ort, um zustandsbehafteten Denial-of-Service(DOS)-Schutz zu implementieren, befindet sich nicht im Framework oder auf der Serverebene, sondern in der Front-End-Infrastruktur.

Ermitteln 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 zeitüberschreitungen. 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 an den Client übergeben als $.connection.hub.lastError.

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 auf lastError das disconnect Ereignis.

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