当前位置: 首页 > 面试题库 >

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

乐正明辉
2023-03-14
问题内容

我有使用socket.io(1.5)的这个简单的node.js Servercode:

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键,则在某些情况下会在断开旧连接之前创建新的连接。一段时间后,我认为它的心跳超时,所有连接都将关闭。查看结果:

 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键,如何防止连接泛滥?

最好的问候马克


问题答案:

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

如果您多次快速按下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总是会立即告诉服务器页面消失时连接。



 类似资料:
  • 问题内容: 我有一个文件,其中我在页面顶部显示外部页面(使用iframe),其他部分是写在文件中的html代码的输出。 HTML代码如下所示: 现在,我想以编程方式刷新页面而不刷新。 我的问题是我可以不刷新页面就刷新页面吗? 答案/提示将不胜感激。 问题答案: 该嵌在主HMTL页面(或在JSP)。因此,如果刷新页面,则肯定会再次加载iframe。 为了避免这种情况,我可以考虑以下两种选择: 使用A

  • 问题内容: 如何定期使用PHP刷新页面?如果我用PHP无法做到这一点,那么最好的推荐方案是什么? 问题答案: 您可以使用PHP来做到这一点: 它会刷新您的当前页面,如果需要将其重定向到另一个页面,请使用以下命令:

  • 问题内容: 我有一个页面,在该页面上我通过代码运行SQL查询,以便每当查看该页面时,查询 就像计数页面视图一样* 运行 * 问题是刷新页面,运行查询和将PAGE REFRESH计为我要避免的PAGE VIEW。 问题: 如何避免呢? 我正在寻找一个简单的解决方案,以便我可以检查 问题答案: 我已经解决了问题…没有会话且没有Cookie的HURRAHHH 该解决方案是PHP:AJAX:JavaScr

  • 假设有一个网页,它是显示现场比赛成绩或股票市场状况或货币兑换率。对于所有这些类型的页面,您需要定期刷新网页。 Java Servlet 提供了一个机制,使得网页会在给定的时间间隔自动刷新。 刷新网页的最简单的方式是使用响应对象的方法 setIntHeader()。以下是这种方法的定义: public void setIntHeader(String header, int headerValue

  • 问题内容: 我有一个应用程序,它使用一个ng-view和多个控制器和视图。如果我浏览根目录,例如:www.domain.com,则一切正常。除非我按Ctrl +R(刷新),否则会显示404错误页面未找到。例如:刷新此页面给我错误。http://domain.com/item/1/。 但是,如果我使用hashbang访问页面,则它可以工作。例如:http://domain.com/#!/item/1

  • 问题内容: 如何强制Web浏览器通过JavaScript硬刷新页面? 硬刷新意味着获取页面的新副本并刷新所有外部资源(图像,JavaScript,CSS等)。 问题答案: 尝试使用: 当此方法接收一个值作为参数时,它将导致该页面始终从服务器重新加载。如果为false或未指定,浏览器 可能会 从其缓存中重新加载页面。