2017-01-29 8 views
7

Ich habe diesen einfachen node.js Servercode mit socket.io (1.5):Node.js Socket.io Aktualisierung der Seite mehr Verbindungen

var io = require('socket.io').listen(8080); 

io.on('connection', function(socket) { 

    console.log(' %s sockets connected', io.engine.clientsCount); 

    socket.on('disconnect', function() { 
     console.log("disconnect: ", socket.id); 
    }); 
}); 

Wenn ich diesem Code und drücken Sie F5 mehrmals ausführen, in einigen Fällen Neue Verbindung wird erstellt, bevor die Verbindung getrennt wird. Nach einiger Zeit denke ich, es ist der Heartbeat Timout, alle Verbindungen werden geschlossen. Sehen Sie das Ergebnis:

2 sockets connected 
3 sockets connected 
4 sockets connected 
5 sockets connected 
6 sockets connected 
7 sockets connected 
8 sockets connected 
9 sockets connected 
10 sockets connected 
11 sockets connected 
disconnect: 0h_9pkbAaE3ftKT9AAAL 
11 sockets connected 
12 sockets connected 
13 sockets connected 
14 sockets connected 
disconnect: oB4HQRCOY1UIvvZkAAAP 
14 sockets connected 
15 sockets connected 
disconnect: LiIN0oDVoqbePgxFAAAR 
15 sockets connected 
16 sockets connected 
17 sockets connected 
18 sockets connected 
disconnect: zxvk-uhWABHzmu1uAAAV 
18 sockets connected 
19 sockets connected 
20 sockets connected 
disconnect: FlboxgTzcjf6ScffAAAY 
20 sockets connected 
21 sockets connected 
disconnect: 9UGXbnzukfGX_UtWAAAa 
21 sockets connected 
disconnect: pAfXOEz6RocKZdoZAAAb 
21 sockets connected 
disconnect: DIhTyVgG2LYBawaiAAAc 
21 sockets connected 
disconnect: W4XOc1iRymfTE2U0AAAd 
21 sockets connected 
disconnect: WZzegGPcoGDNLRTGAAAe 
21 sockets connected 
22 sockets connected 
disconnect: KVR3-fYH0cz77BmgAAAC 
disconnect: ANQknhnxr4l-OAuIAAAD 
disconnect: KZE5orNx6u9MbOArAAAE 
disconnect: TS6LL3asXrcznfcPAAAF 
disconnect: SVNxS3I7KqecdqKhAAAG 
disconnect: IE2WE5Y0PJzvxgBfAAAH 
disconnect: v69bdJav9PjpThBGAAAI 
disconnect: mJKT1ggfOOTshZKgAAAJ 
disconnect: YlycVjdcWe0emCAcAAAK 
disconnect: MoIDJSzP_L-1RUwuAAAM 
disconnect: wAl0x5qwCkrnDDYQAAAN 
disconnect: eiTlPEk2Hx_X-L-fAAAO 
disconnect: KgkrXxzG_EpXOsPTAAAQ 
disconnect: Lvf3kK-6XXEbu3NWAAAS 
disconnect: -hOoGdYOIvVK04K_AAAT 
disconnect: 3EUmaAYpK-U3Ss9tAAAU 
disconnect: HQ6M98FebtKlU3OfAAAW 
disconnect: OwgrbRBYbS4j84nmAAAX 
disconnect: yN8FZAP4RjUNl2MeAAAZ 
disconnect: K9IFTjlgAWzdNfpUAAAf 

Meine Frage ist: Ist das ein Bug oder ist dies das normale Verhalten von socket.io? Wie kann ich verhindern, dass die Verbindung überflutet wird, drücken Sie einfach F5?

Mit freundlichen Grüßen Marc

+0

Der Browser sollte offene WebSockets schließen, wenn Sie den Browser aktualisieren und dann sollten Sie eine Verbindung trennen. Wenn nicht, wäre das ein Browser-Bug. Falls der Browser den webSocket nicht sofort schließt, wird socket.io sehen, dass der Socket nicht mehr aktiv ist (wegen des Heartbeats) und der Socket wird schließlich aufgeräumt. – jfriend00

+0

Das passiert bei allen aktuellen Browsern. – mcbookwood

+0

Wie lange dauert es zwischen dem Drücken von F5 und dem Zeitpunkt, an dem der Server die Verbindung trennt? Es sieht auch so aus, als ob etwas falsch in Ihrer Zählung sein könnte, weil Sie nicht zeigen, dass die Anzahl sinkt, wenn Sie eine Trennung erhalten. – jfriend00

Antwort

10

ich meinen eigenen Test-App gemacht und war in der Lage, um herauszufinden, was los ist.

Wenn Sie F5 ziemlich oft drücken, sammelt es einige zusätzliche socket.io-Verbindungen in Chrome temporär, aber innerhalb einer relativ kurzen Zeit (vielleicht ein paar Minuten), erholt es sich und die Gesamtzahl der verbundenen Sockets ist zurück zu 1.

Nach weiteren Tests stellte ich fest, dass dies kein Browserproblem ist. Dies ist ein Problem bei der Ausführung einer socket.io-Verbindung mit socket.io. Wenn Sie diese im Client ersetzen:

var socket = io(); 

mit diesem:

var socket = io({transports: ['websocket'], upgrade: false}); 

die socket.io NUR erzwingt eine WebSocket verwenden und nie HTTP Polling verwenden, dann verschwindet das Problem.

Also das Problem ist, weil das Standardverhalten für socket.io mit einer HTTP-Abrufversion einer socket.io-Verbindung beginnen soll. Nachdem ein wenig Daten ausgetauscht wurden, versucht socket.io dann, auf einen echten webSocket umzusteigen. Wenn dieser echte webSocket funktioniert, wird die http-Abrufverbindung nicht mehr verwendet.

Aber, wenn Sie einen F5 in der Mitte dieses Übergangs zwischen dem Abrufen und einem echten webSocket treffen, gibt es noch keine beständige Verbindung für socket.io, um zu wissen, dass die Webseite, mit der gerade kommuniziert wurde, verschwunden ist. Alles was es tun kann, ist einige Zeit später herauszufinden, dass es keine eingehende Kommunikation mehr von dieser Webseite gibt und somit sollte es seine socket.io Verbindung bereinigen (es war im Abfragemodus, wenn Sie F5 drücken).

Aber, wenn Sie diesen anfänglichen Abfragemodus mit dem obigen Client-Code ausschalten, dann verwendet es immer nur einen echten webSocket (verwendet nie den simulierten Abfragemodus) und die Browser sind sehr gut beim Aufräumen des webSocket, wenn Sie drücken F5, damit der Server seine socket.io-Verbindung noch nicht fertiggestellt hat (in diesem Fall gibt es noch keine Verbindung, um vorübergehend verwaist zu werden) oder er ist bereits in einen webSocket konvertiert (und der Browser schließt sauber das auf dem F5).

Das ist also eine Einschränkung des Entwurfs des HTTP-Abfragemodus, in dem socket.io startet. Da in diesem Modus keine kontinuierliche Verbindung besteht, gibt es keine sofortige Benachrichtigung durch den Browser, wenn diese Seite durch F5 und ersetzt wird Daher kann der Server nicht wissen, dass der Client gerade verschwunden ist. Aber wenn Sie den HTTP-Polling-Modus überspringen und mit einem echten webSocket beginnen, gibt es kein solches Zeitfenster, in dem eine socket.io-Verbindung existiert, aber kein echter webSocket und somit der Server immer sofort vom Browser informiert wird, der den webSocket schließt Verbindung, wenn die Seite weggeht.

+0

Ah, ok das macht Sinn. Und nach dem Bearbeiten der Socket-Verbindung auf Client und Server tritt das Problem nicht mehr auf. Danke für diese Erklärung! – mcbookwood

Verwandte Themen