Ich verwende SignalR 2.0 mit dem .NET-Client in einer mobilen Anwendung, die verschiedene Arten von Verbindungsabbrüchen verarbeiten muss. Manchmal stellt der SignalR-Client die Verbindung automatisch wieder her - und manchmal muss er durch erneutes Aufrufen direkt HubConnection.Start()
wieder verbunden werden.
Da sich SignalR manchmal auf magische Weise automatisch wieder verbindet, frage ich mich, ob mir eine Funktion oder Konfigurationseinstellung fehlt.
Was ist der beste Weg, um einen Client einzurichten, der sich automatisch wieder verbindet?
Ich habe Javascript-Beispiele gesehen, die das Closed()
Ereignis behandeln und dann nach n Sekunden eine Verbindung herstellen. Gibt es einen empfohlenen Ansatz?
Ich habe die Dokumentation und mehrere Artikel über die Lebensdauer von SignalR-Verbindungen gelesen, bin mir aber immer noch nicht sicher, wie ich mit der erneuten Verbindung des Clients umgehen soll.
quelle
Antworten:
Ich habe das endlich herausgefunden. Folgendes habe ich gelernt, seit ich mit dieser Frage angefangen habe:
Hintergrund: Wir erstellen eine iOS-App mit Xamarin / Monotouch und dem .NET SignalR 2.0.3-Client. Wir verwenden die Standard-SignalR-Protokolle - und es scheint, dass SSE anstelle von Web-Sockets verwendet wird. Ich bin mir noch nicht sicher, ob es möglich ist, Web-Sockets mit Xamarin / Monotouch zu verwenden. Alles wird über Azure-Websites gehostet.
Wir brauchten die App, um schnell wieder eine Verbindung zu unserem SignalR-Server herzustellen, aber wir hatten immer wieder Probleme, bei denen die Verbindung nicht von selbst wiederhergestellt wurde - oder die erneute Verbindung dauerte genau 30 Sekunden (aufgrund eines zugrunde liegenden Protokoll-Timeouts).
Es gab drei Szenarien, auf die wir getestet haben:
Szenario A - Verbindung beim ersten Laden der App herstellen. Dies funktionierte vom ersten Tag an einwandfrei. Die Verbindung wird auch über mobile 3G-Verbindungen in weniger als 0,25 Sekunden hergestellt. (vorausgesetzt, das Radio ist bereits eingeschaltet)
Szenario B - Wiederverbindung mit dem SignalR-Server, nachdem die App 30 Sekunden lang inaktiv / geschlossen war. In diesem Szenario stellt der SignalR-Client möglicherweise ohne besondere Arbeit selbstständig wieder eine Verbindung zum Server her. Es scheint jedoch genau 30 Sekunden zu warten, bevor versucht wird, die Verbindung wiederherzustellen. (viel zu langsam für unsere App)
Während dieser Wartezeit von 30 Sekunden haben wir versucht, HubConnection.Start () aufzurufen, was keine Auswirkungen hatte. Das Aufrufen von HubConnection.Stop () dauert ebenfalls 30 Sekunden. Ich habe einen verwandten Fehler auf der SignalR-Site gefunden, der behoben zu sein scheint , aber wir haben immer noch das gleiche Problem in Version 2.0.3.
Szenario C - Wiederverbindung mit dem SignalR-Server, nachdem die App 120 Sekunden oder länger inaktiv / geschlossen war. In diesem Szenario ist das SignalR-Transportprotokoll bereits abgelaufen, sodass der Client die Verbindung nie automatisch wiederherstellt. Dies erklärt, warum der Client manchmal, aber nicht immer, die Verbindung von selbst wieder herstellte. Die gute Nachricht ist, dass das Aufrufen von HubConnection.Start () fast sofort wie in Szenario A funktioniert.
Es dauerte eine Weile, bis mir klar wurde, dass die Bedingungen für die erneute Verbindung unterschiedlich waren, je nachdem, ob die App 30 Sekunden lang oder mehr als 120 Sekunden lang geschlossen war. Und obwohl die SignalR-Ablaufverfolgungsprotokolle beleuchten, was mit dem zugrunde liegenden Protokoll vor sich geht, glaube ich nicht, dass es eine Möglichkeit gibt, die Ereignisse auf Transportebene im Code zu behandeln. (Das Closed () -Ereignis wird in Szenario B nach 30 Sekunden sofort in Szenario C ausgelöst. Die State-Eigenschaft sagt während dieser Wartezeiten für die erneute Verbindung "Verbunden". Keine anderen relevanten Ereignisse oder Methoden.)
Lösung: Die Lösung liegt auf der Hand. Wir warten nicht darauf, dass SignalR seine Wiederverbindungsmagie ausführt. Wenn die App aktiviert ist oder die Netzwerkverbindung des Telefons wiederhergestellt ist, bereinigen wir einfach die Ereignisse und referenzieren die HubConnection (kann nicht entsorgt werden, da dies 30 Sekunden dauert, hoffentlich wird die Speicherbereinigung dies beheben ) und Erstellen einer neuen Instanz. Jetzt funktioniert alles super. Aus irgendeinem Grund dachte ich, wir sollten eine dauerhafte Verbindung wiederverwenden und die Verbindung wiederherstellen, anstatt nur eine neue Instanz zu erstellen.
quelle
Das Einstellen eines Timers für das nicht verbundene Ereignis, um automatisch zu versuchen, die Verbindung wiederherzustellen, ist die einzige mir bekannte Methode.
In Javascript wird es so gemacht:
Dies ist der empfohlene Ansatz in der Dokumentation:
quelle
reconnecting
Ereignis abonniert , das ausgelöst wird, sobald der Hub die Verbindung verliert, und diese Variable (zshouldReconnect
. B. ) auf true gesetzt hat. Also habe ich Ihr Beispiel angepasst, um diese Variable zu überprüfen. Es sieht gut aus.Da das OP nach einem fragt .NET-Client (eine Winform-Implementierung unten),
quelle
Ich füge ein Update für die Antwort von ibubi hinzu . Vielleicht braucht es jemand. Ich habe festgestellt, dass in einigen Fällen signalr kein "geschlossenes" Ereignis auslöst, nachdem die Wiederverbindung gestoppt wurde. Ich habe es mit dem Ereignis "StateChanged" gelöst. Methode, die eine Verbindung zum SignalR-Server herstellt:
Methode zum erneuten Verbinden:
Methode für endlose Versuche, eine Verbindung zum Server herzustellen (auch ich verwende diese Methode zum Herstellen der ersten Verbindung):
quelle
Sie könnten versuchen, die Servermethode von Ihrem Android aus aufzurufen, bevor Sie den Status der erneuten Verbindung starten, um ein Problem mit der magischen erneuten Verbindung zu vermeiden.
SignalR Hub C #
In Android
quelle