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

Javascript Node.js Socket.io页面刷新多个连接,javascript,node.js,sockets,socket.io,Javascript,Node.js,Sockets,Socket.io,我使用socket.io(1.5)编写了这个简单的node.js服务器代码: 如果我运行此代码并多次按F5,在某些情况下,会在断开旧连接之前创建新连接。过了一段时间,我想是心跳超时了,所有的连接都会关闭。见结果: 2 sockets connected 3 sockets connected 4 sockets connected 5 sockets connected 6 sockets connected 7 sockets connected 8 sockets connec

我使用socket.io(1.5)编写了这个简单的node.js服务器代码:

如果我运行此代码并多次按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键

致意
Marc

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

如果您多次快速点击F5,它确实会在Chrome中临时积累一些额外的socket.io连接,但在相对较短的时间内(可能几分钟),它会恢复,连接的socket总数会回到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轮询连接

但是,如果在轮询和真正的WebSoCo之间的过渡过程中碰到了F5,那么对于SoCKE.IO还没有持久的连接来知道它刚刚与之通信的网页现在不见了。因此,它所能做的就是在一段时间后发现不再有来自该网页的任何传入通信,因此它应该清除它的socket.io连接(当您点击F5时,它处于轮询模式)

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


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

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

示例:back:socket.io 3.0.3

示例:前端:socket io客户端3.0.3

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

从…导入io


const socket=io('http//localhost:3000')->server node

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

socket.on(“连接错误”,(错误)=>{ console.log(
connect_错误,原因是${err.message}
); }))


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

当你刷新浏览器时,浏览器应该关闭打开的webSocket,然后你应该断开连接。如果没有,那将是浏览器错误。如果浏览器没有立即关闭webSocket,socket.io将看到套接字不再处于活动状态(因为心跳)套接字最终将被清除。所有实际浏览器都会发生这种情况。从按F5到服务器最终断开连接之间的时间间隔是多少?由于断开连接时没有显示计数下降,因此计数也可能出错。如果只按F5一次,则断开连接nect马上就来了。但是如果你按F5键的速度足够快,一些磁盘就会“丢失”。我不认为计数器是错误的,因为示例服务器只在新连接打开时才计算。我对计数器的评论是,您收到一条断开连接消息,但计数没有下降。这在您的日志中似乎非常明显。如果只是快速刷新导致问题,我不知道您为什么担心I有问题。他们会在一段短时间后自行清理,因此不会意外地长期积累任何东西。这会导致任何真正的问题吗?您可以缩短socket.io不活动超时时间,以便他们更快地清理自己,但这可能会造成其他妥协,因此如果这不是真正的问题,我不会更改。啊,好的,这很有意义。在编辑客户端和服务器上的套接字连接后,问题不再出现。感谢您的解释!@NikDrosakis-它确实解决了这个特定问题中提到的问题。您显然是指一些不同类型的F5问题。我建议您编写自己的问题这说明了您自己的问题。@jfriend00-这对解决页面刷新问题非常有帮助。我曾使用flask socket io作为后端,但这种技术应该始终适用于客户端socket-io。这完全解决了我的问题,前端和后端版本不同。此答案与问题无关
var socket = io({transports: ['websocket'], upgrade: false});