我有这个简单的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?
最诚挚的问候 马克
答案 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轮询,然后问题就消失了。
因此,问题是因为socket.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}
);
});
这样,我可以知道错误,我希望这可以帮助某人