Node.js Socket.io page refresh multiple connections

22,818

Solution 1

I made my own test app and was able to figure out what is going on.

If you hit F5 quite fast multiple times, It does temporarily accumulate some extra socket.io connections in Chrome, but within a relatively short time (maybe a few minutes), it recovers and the total count of connected sockets is back to 1.

After further testing, I discovered that this is not a browser issue. This is an issue with how socket.io starts a socket.io connection. If you replace this in the client:

var socket = io();

with this:

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

which forces socket.io to ONLY use a webSocket and never use HTTP polling, then the problem disappears.

So, the issue is because the default behavior for socket.io is to start with an http polling version of a socket.io connection. After a little data is exchanged, socket.io will then attempt to switch over to a real webSocket. If that real webSocket works, then it will stop using the http polling connection.

But, if you hit an F5 in the middle of this transition between polling and a real webSocket, there is no persistent connection yet for socket.io to know that the web page it was just communicating with is now gone. So, all it can do is to figure out some time later that there is no longer any incoming communication from that web page and thus it should clear up it's socket.io connection (it was in polling mode when you hit F5).

But, if you turn off that initial polling mode with the above client code, then it only ever uses a real webSocket (never uses the simulated polling mode) and the browsers are very good at cleaning up the webSocket when you hit F5 so the server either hasn't finished establishing it's socket.io connection (in which case there's no connection yet to get temporarily orphaned) or it's already converted over to a webSocket (and the browser will cleanly close that on the F5).

So, this is a design limitation of the http polling mode that socket.io starts in. Since there is no continuous connection when in that mode, there is no immediately notification by the browser when that page is replaced with F5 and thus the server has no way of knowing that the client just disappeared. But, if you skip the http polling mode and start with a real webSocket, then there is no such window of time where there's a socket.io connection, but no real webSocket and thus the server is always told immediately by the browser closing the webSocket connection when the page goes away.

Solution 2

Solution: update the versions of your socket.io packages front and back

example : back : socket.io 3.0.3

example : front : socket-io-client 3.0.3

now is compatible and transport socket is websocket and not polling !

import io from ....

const socket = io('http//localhost:3000') -> server node

Share:
22,818
mcbookwood
Author by

mcbookwood

Updated on July 09, 2022

Comments

  • mcbookwood
    mcbookwood almost 2 years

    i have this simple node.js Servercode using socket.io (1.5):

    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);
        });
    });
    

    If i run this code und press F5 several times, in some cases new connection is created, before the old one is disconnected. After some time, i think its the Heartbeat Timout, all the connections will be closed. See the result:

     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
    

    My Question is: Is this a Bug or is this the normal behavior of socket.io? How can i prevent the connection flooding, simple pressing F5?

    Best Regards Marc