Node.js Socket.io页面刷新多个连接 [英] Node.js Socket.io page refresh multiple connections

查看:318
本文介绍了Node.js Socket.io页面刷新多个连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用socket.io(1.5)使用了以下简单的node.js Servercode:

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

如果我运行此代码并按几次F5键,则在某些情况下会在断开旧连接之前创建新的连接.一段时间后,我认为它的心跳超时,所有连接都将关闭.查看结果:

 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

我的问题是: 这是Bug还是socket.io的正常行为?只需按F5键,如何防止连接泛滥?

最好的问候 马克

解决方案

我制作了自己的测试应用程序,能够弄清楚发生了什么.

如果您多次快速按下F5键,它确实会在Chrome中临时积累一些额外的socket.io连接,但是在相对较短的时间内(可能是几分钟),它会恢复,并且已连接的套接字总数将恢复为1.

经过进一步测试,我发现这不是浏览器问题.这是socket.io如何启动socket.io连接的问题.如果您在客户端中替换它:

var socket = io();

与此:

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

这迫使socket.io仅使用webSocket而不使用HTTP轮询,然后问题消失了.

因此,问题是因为s​​ocket.io的默认行为是从socket.io连接的http轮询版本开始.交换少量数据后,socket.io将尝试切换到实际的webSocket.如果该真正的webSocket有效,则它将停止使用http轮询连接.

但是,如果您在轮询和实际的webSocket之间的过渡过程中碰到F5,则socket.io知道与之通信的网页现在不存在了,因此没有持久的连接.因此,它所能做的就是在一段时间后确定该网页不再有任何传入通信,因此应清除它的socket.io连接(在您按F5时处于轮询模式).

但是,如果您使用上述客户端代码关闭了初始轮询模式,则它只会使用真实的webSocket(永远不会使用模拟轮询模式),并且当您按F5键时,浏览器会非常擅长清理webSocket因此服务器可能尚未完成建立socket.io连接的情况(在这种情况下,尚无连接可暂时孤立),或者服务器已转换为webSocket(浏览器将完全清除F5上的连接).

因此,这是socket.io始于http轮询模式的设计限制.由于在该模式下没有连续连接,因此当该页面被F5替换时浏览器不会立即发出通知,因此服务器无法知道客户端刚刚消失.但是,如果您跳过http轮询模式并从一个真正的webSocket开始,那么就没有socket.io连接的时间窗口,而是没有真正的webSocket,因此浏览器总是会立即通过关闭webSocket来告知服务器页面消失时连接.

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

解决方案

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.

这篇关于Node.js Socket.io页面刷新多个连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆