Ü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:
- Behandeln von Verbindungslebensdauerereignissen in der Hub-Klasse
- Behandeln von Verbindungslebensdauerereignissen in JavaScript-Clients
- Behandeln von Verbindungslebensdauerereignissen in .NET-Clients
In diesem Thema verwendete Softwareversionen
- Visual Studio 2017
- .NET 4.5
- SignalR, Version 2
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.
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.
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.
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 dasReconnecting
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.
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.
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.
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.
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 DisconnectTimeout
KeepAlive
festlegen möchten, legen Sie nach DisconnectTimeout
festKeepAlive
. 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 derStart
-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 derStop
-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.lastError
an 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 lastError
disconnect
-Ereignis.
$.connection.hub.disconnected(function () {
if ($.connection.hub.lastError)
{ alert("Disconnected. Reason: " + $.connection.hub.lastError.message); }
});