Ü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:
- 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 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.
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.
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.
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 gehenReconnecting
.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.
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.
Timeout- und Keepalive-Einstellungen
Die StandardConnectionTimeout
DisconnectTimeout
- 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.
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 KeepAlive
auch DisconnectTimeout
nach DisconnectTimeout
dem 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 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 nur nach einem timeout für die erneute Verbindung ausgeben, nicht nach einem normalen Ende der SignalR-Verbindung, die durch aufrufen derStop
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); }
});