我制作了自己的测试应用程序,能够弄清楚发生了什么。
如果您多次快速按下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总是会立即告诉服务器页面消失时连接。



