Ich habe kürzlich einen lokalen WebSocket-Server eingerichtet, der einwandfrei funktioniert. Ich habe jedoch einige Probleme zu verstehen, wie ich mit einem plötzlichen Verbindungsverlust umgehen soll, der weder vom Client noch vom Server absichtlich ausgelöst wurde, z. B.: Server verliert Strom, Ethernet-Kabel herausgezogen usw. Ich möchte, dass der Client innerhalb von ca. 10 Sekunden weiß, ob die Verbindung unterbrochen wurde.
Clientseitig ist die Verbindung einfach:
var websocket_conn = new WebSocket('ws://192.168.0.5:3000');
websocket_conn.onopen = function(e) {
console.log('Connected!');
};
websocket_conn.onclose = function(e) {
console.log('Disconnected!');
};
Ich kann die Verbindungstrennung manuell auslösen, was einwandfrei funktioniert.
websocket_conn.close();
Aber wenn ich einfach das Ethernet-Kabel an der Rückseite des Computers herausziehe oder die Verbindung deaktiviere, onclose wird nicht angerufen. Ich habe in einem anderen Beitrag gelesen, dass es irgendwann aufgerufen wird, wenn TCP einen Verbindungsverlust feststellt, aber nicht in der Zeit, die ich brauche, da der Standardwert für Firefox meiner Meinung nach 10 Minuten beträgt und ich das eigentlich nicht tun möchte rund Hunderte von Computern about:config diesen Wert ändern. Der einzige andere Vorschlag, den ich gelesen habe, ist die Verwendung einer „Ping/Pong“-Keep-Alive-Abfragemethode, die der Idee von Websockets zu widersprechen scheint.
Gibt es eine einfachere Möglichkeit, diese Art von Verbindungsabbruchverhalten zu erkennen? Sind die alten Beiträge, die ich lese, technisch noch aktuell und die beste Methode ist immer noch der „Ping/Pong“-Stil?
Wenn Sie sich nicht mit Keep-Alive-Tokens, der Planung von Wiederverbindungsversuchen usw. befassen möchten, sollten Sie eine bewährte Bibliothek verwenden. socket.io kommt in den Sinn.
– Denys Séguret
17. November 2014 um 10:55
Sie müssen die Ping-Pong-Methode hinzufügen
Erstellen Sie beim Empfang einen Code auf dem Server __Klingeln__ schicken __pong__ zurück
Der JavaScript-Code ist unten angegeben
function ping() {
ws.send('__ping__');
tm = setTimeout(function () {
/// ---connection closed ///
}, 5000);
}
function pong() {
clearTimeout(tm);
}
websocket_conn.onopen = function () {
setInterval(ping, 30000);
}
websocket_conn.onmessage = function (evt) {
var msg = evt.data;
if (msg == '__pong__') {
pong();
return;
}
//////-- other operation --//
}
Dies war für mich in Kombination mit dieser Websocket-Implementierung zum erneuten Verbinden hier wirklich nützlich: github.com/joewalnes/reconnecting-websocket mit einer Einschränkung: Ich musste den Intervall-Timer auch einer Variablen zuweisen und ihn innerhalb der Ping-Timeout-Funktion löschen.
– Löwe
31. Juli 2019 um 12:40 Uhr
Was nützt Websocket, wenn Sie damit Umfragen durchführen 🙂
– Steve Moretz
18. Oktober 2021 um 7:51 Uhr
@stevemoretz Das frage ich mich tatsächlich
– manudicri
20. Januar 2022 um 21:58
Websockets scheinen eine wirklich dünne Schicht zu TCP/IP zu sein. Wenn Sie also eine zusätzliche Funktion über die aktuelle Implementierung von TCP/IP hinaus implementieren müssen, müssen Sie diese selbst hinzufügen. Daher gab der Antwortende an, dass Sie Ping/Ping selbst hinzufügen müssen. Es wäre jedoch schön, wenn WebSockets dies eingebaut hätten, damit es konfigurierbar und allgemeiner wäre, da es anscheinend ein häufiges Ärgernis ist.
– LeanMan
27. Januar 2022 um 9:15 Uhr
BetreffCurio
Dies war die Lösung, die ich letztendlich gefunden habe und die vorerst gut zu funktionieren scheint. Sie ist völlig spezifisch für die Einrichtung meines Projekts und basiert auf Kriterien, die ursprünglich nicht in meiner Frage erwähnt wurden, aber sie könnte für jemand anderen nützlich sein wenn sie zufällig das Gleiche tun.
Die Verbindung zum Websocket-Server erfolgt innerhalb eines Firefox-Add-ons und standardmäßig hat das TCP-Setup von Firefox eine Zeitüberschreitung von 10 Minuten. Weitere Details können Sie mit einsehen about:config und Suche nach TCP.
Firefox-Add-ons können auf diese Parameter zugreifen
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
und ändern Sie diese Parameter auch, indem Sie den Zweig und die Präferenz zusammen mit dem neuen Wert angeben
Jetzt hat jeder Computer, auf dem das Add-on installiert ist, eine Zeitüberschreitung von 10 Sekunden für TCP-Verbindungen. Wenn die Verbindung unterbrochen wird, wird die onclose Es wird ein Ereignis ausgelöst, das eine Warnung anzeigt und außerdem versucht, die Verbindung wiederherzustellen
Ich glaube, Ihnen fehlen eine Handvoll Variablen und Codezeilen. obj.action === ‘join’ wo kommt das überhaupt her? Und ich denke, Ihre Variable fehlt, um Ihren setTimeout zu löschen.
– Brad Vanderbush
30. Mai 2020 um 15:00 Uhr
Der obj.action ===-Beitritt erfolgt durch Klicken auf die Schaltfläche „Beitreten“. Der setTimeout wird im keepAlive referenziert.
– Jade
16. Juni 2020 um 17:16 Uhr
Warum wss.broadcast zweimal definieren?
– Temirbek
9. November 2021 um 9:25 Uhr
Das ist nur ein Tippfehler, behoben, Ty
– Jade
22. November 2021 um 18:22 Uhr
vtortola
Das Websocket-Protokoll definiert Kontrollrahmen für Tischtennis und Tischtennis. Wenn also der Server einen Ping sendet, antwortet der Browser mit einem Pong, und umgekehrt sollte es auch funktionieren. Wahrscheinlich implementiert der von Ihnen verwendete WebSocket-Server sie, und Sie können ein Timeout definieren, in dem der Browser antworten muss, sonst gilt er als tot. Dies sollte für Ihre Implementierung sowohl im Browser als auch auf dem Server transparent sein.
Auch relevant: WebSockets Ping/Pong, warum nicht TCP Keepalive?
Okay, ich komme zu spät zur Party, hoffe aber, dass ich hier etwas hinzufügen kann. Meine TypeScript-Implementierung in einem Angular App zu handhaben WebSocket Verbindung unterbrochen. Dies wird nicht verwendet PING PONG Strategie, um zu vermeiden, dass der Server ständig ausgelastet ist. Dies beginnt erst dann mit dem Versuch, eine Verbindung herzustellen, wenn die Verbindung verloren geht, und versucht es alle 5 Sekunden so lange, bis die Verbindung erfolgreich hergestellt wurde. Auf geht’s:
Und das ist es. Wenn Sie die WebSocket-Verbindung zu einem bestimmten Zeitpunkt schließen möchten, legen Sie fest selfClosing = true. Dies würde den Versuch unterbinden, die Verbindung erneut herzustellen. Hoffe das hilft. Ich bin sicher, dass derselbe Code nativ verwendet werden kann JS sowie.
Das ist sehr nützlich für die Wiederherstellung der Verbindung, aber ich denke, das Problem des OP bestand darin, dass es zu lange gedauert hat, bis es erkannt hat, dass die Verbindung verloren gegangen ist.
– Andrew W. Phillips
1. September 2022 um 7:09
Das ist sehr nützlich für die Wiederherstellung der Verbindung, aber ich denke, das Problem des OP bestand darin, dass es zu lange gedauert hat, bis es erkannt hat, dass die Verbindung verloren gegangen ist.
– Andrew W. Phillips
1. September 2022 um 7:09
14519200cookie-checkUmgang mit Verbindungsverlusten mit WebSocketsyes
Wenn Sie sich nicht mit Keep-Alive-Tokens, der Planung von Wiederverbindungsversuchen usw. befassen möchten, sollten Sie eine bewährte Bibliothek verwenden. socket.io kommt in den Sinn.
– Denys Séguret
17. November 2014 um 10:55