我有这个使用 socket.io (1.5) 的简单 node.js 服务器代码:
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 轮询,然后问题就消失了。
所以,问题是因为 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当页面消失时连接。
关于javascript - Node.js Socket.io 页面刷新多个连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41924713/
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
我正在尝试按0-9和a-z的顺序创建数字和字母列表。我有一组值value_array=['0','1','2','3','4','5','6','7','8','9','a','b','光盘','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','','u','v','w','x','y','z']和一个组合列表的数组,按顺序,这些数字可以产生x个字符,比方说三个list_array=[]和一个当前字母和数字组合的数组(在将它插入列表数组之前我会把它变成一个字符串,]current_combo['0','0','0']