Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
312 views
in Technique[技术] by (71.8m points)

javascript - Node.js Socket.io page refresh multiple connections

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...