Node.js Socket.io页面刷新多个连接

时间:2017-01-29 18:56:40

标签: javascript node.js sockets socket.io

我有这个简单的node.js Servercode使用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);
    });
});

如果我运行此代码并按F5几次,在某些情况下会创建新连接,然后再断开旧连接。过了一段时间,我认为它的Heartbeat Timout,所有的连接将被关闭。看结果:

 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?

最诚挚的问候 马克

3 个答案:

答案 0 :(得分:21)

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

如果你多次快速点击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连接。

答案 1 :(得分:0)

解决方案:前后更新socket.io软件包的版本

示例:后退:socket.io 3.0.3

示例:前面:socket-io-client 3.0.3

现在兼容,并且传输套接字是websocket而不是轮询!

从...导入io。

const socket = io('http // localhost:3000')->服务器节点

答案 2 :(得分:0)

我遇到了同样的错误,我与同一个用户建立了多个连接,错误是我在后端使用了不同的版本,而我在前端添加了这段代码:

socket.on("connect_error", (err) => { 控制台日志(connect_error due to ${err.message}); });

这样,我可以知道错误,我希望这可以帮助某人