【发布时间】:2014-01-13 15:56:47
【问题描述】:
使用
网络应用程序。 NodeJS + Socket.io(仅限 websockets,启用心跳)。
问题
我的应用程序工作正常(它连接到 Socket.io,它正确地发出/接收消息),但我检测到随机断开连接,而不是因为心跳超时。即使服务器收到来自客户端的心跳包,它仍然有可能在几秒钟内断开该客户端的连接。我不明白原因。它几乎是随机发生的,大约每 3-15 分钟一次。更改 socket.io 配置似乎不会影响频率。
这是日志,它清楚地表明断开连接的原因是不是心跳超时,而是传输端(套接字端):
日志:
debug: emitting heartbeat for client cTVCsv2GS2R_lh3Ecao-
debug: websocket writing 2::
debug: set heartbeat timeout for client cTVCsv2GS2R_lh3Ecao-
debug: got heartbeat packet
debug: cleared heartbeat timeout for client cTVCsv2GS2R_lh3Ecao-
debug: set heartbeat interval for client cTVCsv2GS2R_lh3Ecao-
info: transport end (socket end)
// ^ Why?
debug: set close timeout for client cTVCsv2GS2R_lh3Ecao-
debug: cleared close timeout for client cTVCsv2GS2R_lh3Ecao-
debug: cleared heartbeat interval for client cTVCsv2GS2R_lh3Ecao-
SOCK 25.12 22:23:20.675 disconnection from IO detected (USER1)
// ^ This means disconnected event fired
debug: discarding transport
debug: client authorized
info: handshake authorized GPBLHsqhhrdsTeqTcao_
debug: setting request GET /socket.io/1/websocket/GPBLHsqhhrdsTeqTcao_?conftoken=20519986772
debug: set heartbeat interval for client GPBLHsqhhrdsTeqTcao_
debug: client authorized for
debug: websocket writing 1::
debug: client authorized for /io/activity
debug: websocket writing 1::/io/activity
SOCK 25.12 22:23:23.005 reconnected to IO (USER1)
配置
客户:
socket = io.connect('/io/activity',{'max reconnection attempts':Infinity})
服务器:
io = require('socket.io').listen(server, {
log: true
, "close timeout": 120
, "heartbeat timeout": 120
, "heartbeat interval": 30
, "transports": ["websocket"]
})
io.enable('browser client minification')
io.enable('browser client etag')
io.enable('browser client gzip')
【问题讨论】:
-
从外观上看,这似乎是心跳超时,因为在您的日志中服务器第二次应该获得心跳数据包,它记录了一个传输端。你能确认收到了心跳包然后传输结束了吗?
-
是的,我确定不是心跳超时。起初,当它实际上是超时时,日志写入“info:transport end(心跳超时)”,而不是“info:transport end(socket end)”。此外,如果我关闭心跳或将其超时设置为 2 小时,问题仍然存在。
-
您使用的是哪个版本? 0.9 版本似乎经常出现问题:github.com/LearnBoost/socket.io/issues/777
-
是的,我使用的是 0.9.16。但我不确定这个错误是否与我的问题有关。我没有像线程中的人那样经常断开连接,而是随机断开连接。断开连接的频率不取决于超时,而在这个线程中很明显 - 它取决于。据说“一分钟后”和“25 秒后”——实际上是心跳配置的默认值。我的每 3-15 分钟发生一次。
-
如果你只需要 WebSockets 协议,我建议使用纯 WebSockets 模块,而不是 socket.io。 Socket.io 为其他协议提供了层和一些“心跳”实现,但为 WebSockets 保留了它,这实际上没有意义,因为 WebSockets 是持久的 TCP 连接,并且在断开连接时双方都知道 TCP 连接丢失。因此,由于需要支持多种协议,socket.io 中的 WebSockets 遭受了一些额外的层。使用这个:github.com/einaros/ws 用于 WebSockets 会更有效率。
标签: node.js websocket socket.io