Socket.io: 重新连接后打开多个插座

创建于 2011-07-28  ·  54评论  ·  资料来源: socketio/socket.io

我在我的socket.io应用程序和其他应用程序上都注意到了这一点。 发生重新连接时,通常会打开一个客户端中的多个套接字,这种情况永远不会发生。

这是断开/重新连接时从我自己的测试应用程序获得的日志。

**断开连接* *延迟重新连接1000次尝试:1
**延迟重新连接尝试2000次:2* *使用xhr-polling连接
**连接xhr-polling* *重新连接传输类型xhr-polling尝试:2
** 连接的* *已连接

发生这种情况时,我会收到重复的消息,每个连接的套接字都会发送一条消息,即使应该只有一条。 Firebug确认,实际上有来自客户端的两个套接字已连接。 我最好的猜测是,这在客户端代码中,也许没有关闭第一次重新连接尝试。

当然,真正的问题可能是为什么首先要断开连接?

Socket.IO client bug

最有用的评论

进一步调查一下,似乎我找到了造成问题的原因。 这不是错误,而是我个人对客户端代码的错误实现。 facepalm这是我最初拥有的:

问题:

var socket = io.connect();

socket.on('connect', function () {

  console.log('User connected!');

  socket.on('message', function(message) {

    console.log(message);

  });

});

当客户端重新连接时,上述客户端JavaScript导致多次调用console.log()。 这是我用以下内容替换的内容:

解:

var socket = io.connect();

socket.on('connect', function () {

  console.log('User connected!');

});

socket.on('message', function(message) {

  console.log(message);

});

现在,当客户端重新连接到服务器时,不会来回发送多个消息。 其他人可以确认他们的客户端代码更改可以解决此问题吗?

所有54条评论

断开连接被触发,因为从技术上讲,客户端已与服务器断开连接。 并断开连接,直到再次触发重新连接事件。

但是其余的是一个错误。

我认为这也是我的应用程序中存在错误的原因-

在服务器端,我在mongodb上创建了一个可尾游标,以在每次有新插入时触发。 然后,此消息通过io.sockets.emit()发送给所有连接的人。

但是,我不是在每个事件中仅收到一条消息,而是在客户端收到多条重复消息。

我的互联网连接非常不可靠,所以我猜想这个错误也会影响我的代码。

你们在使用expressjs吗? 我在使用express时遇到了这个问题,没有重写它就可以了。

Express绝对与此@mfkp无关,一定是在做一些奇怪的事情

同意@visionmedia ,这是socket.io中的错误,而不是Express。 由于当前的重新连接实现仍是针对0.6设计的,因此缺少一些检查和清理。

知道了没关系,继续;-)

为此+1。 我们的聊天应用中的间歇性问题,其中socket.io打开了多个连接。 然后,客户端收到所有发射的欺骗。

+1。 Websockets和Chrome。 笔记本电脑进入睡眠状态->唤醒后应用重新连接->两次事件。 仅在连接到远程服务器时发生。 无法在本地重现此内容,必须是一些重新连接/网络延迟问题。

有什么解决方法可以摆脱多个连接吗?例如从客户端,如果我执行socket.disconnect(),它将断开所有连接吗? 由于我要避免多次更新。 以下工作吗?
套接字= io.connect(URL)
socket.on('connect',function(){
if(multipleConnect){
socket.disconnect();
socket.removeAllListeners('connect');
io.sockets = {};
套接字= io.connect(URL);
socket.on('connect',functionToConnect);
}
})

请阅读此https://github.com/LearnBoost/socket.io/issues/474#issuecomment -2833227。
它解释了为什么会发生此错误以及如何重现该错误。

@ 3rd-Eden-知道此修复程序在您的待办事项列表/优先级上的位置吗? 我有一个正在构建的应用程序,正计划将其用于此应用程序,希望能够告诉我的客户它可以从iOS设备正确重新连接。 在将应用程序置于后台或使设备进入睡眠状态后,它将断开连接。

还是您对我如何编码变通办法有任何想法? 在过去的几天里,我一直在做一些事情,但是最好的情况似乎总是使太多的连接保持打开状态,并丢弃所有套接字存储的数据。 数据不是世界末日,我可以使用客户端的重新连接触发器来解决该问题,但是并发连接有点难看。

谢谢!

@cris我不确定这与您提到的错误相同。 我有一个非常简单的错误示例,但没有降低服务器速度。

我可以通过以下方式清楚地重现此问题:

  1. 实施一个简单的心跳客户端,该客户端每隔1秒发送一次心跳。
  2. 计算服务器端的新连接数。
  3. 计算服务器端断开连接的数量。
  4. 启动服务器并与客户端建立连接。
  5. 断开客户端和服务器之间的网络连接。
  6. 等待服务器超时并发出断开连接事件。
  7. 重新连接网络连接。

观察到客户端重新连接时,它会创建2-4个连接,并为每个连接发出一个“连接”事件。 服务器从客户端接收2-4个连接,并为每个连接发出“连接”事件。 客户端永远不会关闭任何错误启动的连接。

server.js: https
client.html: https ://gist.github.com/1717648

谢谢。 我确实认为应该优先考虑此错误。 许多不了解的商业公司都试图雇用人们根据socket.io框架进行开发,并认为它运作良好。 当然,socket.io是免费的,所以也许这家商业公司应该开始研究商业产品。 但是,我再次认为,这确实需要作为非常高的优先级进行优先处理。 此bug从0.7.0开始存在,并且很容易重现。

@davidfooks ,@theyak。 我很久以前为我解决了这个问题,并且可以正常工作。

要修复,您应该:

  1. 应用此补丁: https :
  2. 禁用AJAX握手(并仅通过JSONP进行握手),如pull-request注释中所述。

如何禁用AJAX握手? 我假设您仍然可以使用所有连接类型,这只会影响握手吗?

+1,请解决此问题:)

我在重新连接问题上有相同的多个连接。 我认为这是一个严重的问题...
原因是调用了Socket.connect方法,但仅在握手完成后将conneting标志设置为true,以防在握手过程中唤醒其中一个matbeReconnect计时器(处理重新连接的计时器)时,它们将调用Socket。再次连接导致多次重新连接。
我已经通过在Socket.connect方法的开头调用self.reconnecting解决了这个问题。

创建了一个补丁程序: https :

有机会合并吗?
此错误也在我的应用程序中造成了严重的错误。

该错误仍然存​​在。 尝试了两个补丁。 没有成功

+1我使用xhr-polling遇到了很多问题,但我还没有尝试过补丁

+1,我也有重复重新连接的问题。

无论何时重新启动Node.js(即,通过超级用户运行),我的客户端都会重新连接X次,即从客户端最初连接的点开始,Node.js已重新启动的次数。 该错误导致每次从客户端重新连接发出一次事件-这不仅仅是重复的问题。

我在客户端尝试了socket.on('disconnect', function() { socket.disconnect(); }); ,但这不起作用。 :/

进一步调查一下,似乎我找到了造成问题的原因。 这不是错误,而是我个人对客户端代码的错误实现。 facepalm这是我最初拥有的:

问题:

var socket = io.connect();

socket.on('connect', function () {

  console.log('User connected!');

  socket.on('message', function(message) {

    console.log(message);

  });

});

当客户端重新连接时,上述客户端JavaScript导致多次调用console.log()。 这是我用以下内容替换的内容:

解:

var socket = io.connect();

socket.on('connect', function () {

  console.log('User connected!');

});

socket.on('message', function(message) {

  console.log(message);

});

现在,当客户端重新连接到服务器时,不会来回发送多个消息。 其他人可以确认他们的客户端代码更改可以解决此问题吗?

你好我遇到过同样的问题。 当我重新启动节点时(或连接超时时),并且客户端重新连接时,我收到服务器在n次之前发出的相同消息(其中n是重新连接的次数)。
我通过从socket.on('connect'function(){...});内部移动所有处理程序来解决此问题。 功能之外。

上面的代码完成了它所需要的。
这是我从邮件列表中得到的完整答案:
https://groups.google.com/forum/?hl=zh_CN&fromgroups#!topic/socket_io/X9FRMjCkPco

@xdanx ,太棒了,谢谢您的回复。

是的,这似乎也对我有用:将socket.on('message')代码与'connect'事件代码分开

但是“连接”呢?
回调中的“套接字”对象又如何呢?

/ edit没关系,我看到客户端上有“连接”。 当我没有这样做时,重新连接垃圾邮件仍然存在问题。 但这是在0.9.6中

我似乎也遇到了同样的问题...尝试了将消息代码移动到单独的块上的上述修复方法。.但是注意到我从来没有在一起。

在0.9.8中对此有任何其他新闻吗?

我也有同样的问题。 我已经安装了0.9.10。 有任何解决这个问题的方法吗? :(
顺便说一句,它已经一年多了,还没有修复.. :(

编辑。

当我仅使用jsonp-polling时,问题似乎消失了。
io.set('transports',['jsonp-polling']);

我也有同样的问题。
插座。 [email protected]
节点v0.8.8

@semprom我认为使用jsonp-polling可以解决此问题,因为它可能只与websocket连接有关。

不幸的是,对于我来说,我的整个实现方式都依赖于尽可能快的反馈,因此与轮询相比,websockets效果最好。而且,由于我控制着连接的客户端,因此除了这个问题之外,我没有其他理由其他。

请注意,来自同一客户端重新连接的多个连接具有相同的socket.id 。 因此,您可以维护自己的套接字ID列表,而忽略重复项以解决此问题。

@KasperTidemann谢谢。 它解决了这个问题。

@esanai没问题,很高兴它起作用了!

嗨,我有同样的问题,我注意到每次重新连接时,都会创建一个新的客户端套接字ID。 解决方案是使用io.set('transports',['jsonp-polling']); 或使用KasperTidemann的解决方案?

@KasperTidemann,我的天哪,这正是我遇到的问题的答案! 看到这个提交: https :

我可以在单个node.js文件中使用以下简单的客户端和服务器代码,在连接错误后重现双重连接事件:

"use strict";

var server = require('socket.io');
var client = require('socket.io-client');

setTimeout(function () {
    var io = server.listen(8888);

    io.of('/chat').on('connection', function (socket) {
        console.log('Server: /chat connection');
        socket.emit('greeting', 'Hello, who are you?');
    });

    io.sockets.on('connection', function (socket) {
        console.log('Server: connection');
    });
}, 2000);

var socketAddress = 'http://localhost:8888/chat';
var socket = client.connect(socketAddress);

socket.on('connect', function () {
    console.log("Client: connect");
});

socket.on('greeting', function (data) {
    console.log("Client: greeting: ", data);
});

socket.on('error', function () {
    console.log("Client: error");
    socket.socket.reconnect();
});

是否有任何回合或修复的工作?

抱歉,我还发布了此问题以发布#474。

我可以使用具有iOS 9.3.2和Chrome版本50.0.2661.95的iPhone以及具有Socket.IO版本1.4.6的Safari在iOS上相当一致地重现此错误。

我只能在移动设备上重现此内容,并且该页面将我的页面挂在对socket.io的请求上。

我有一个简单的.on('connect',function(socket){console.log('Connected');}); 并在发生错误时记录两次Connected,这使我相信它试图同时打开多个套接字连接。

screenshot 2016-05-27 13 03 44

有谁知道解决方法?

为什么关闭此问题?

我的示例代码2014年4月14日不再产生双重连接事件。 “ / chat”有一个连接事件,套接字本身有一个。 这似乎是合理的。

即使在客户端中也没有错误。

这与socket.io 1.4.8和节点6.3.0一起使用。

此错误正在影响我的atm。

显然,当将socket_handler与路由放置在一起时,将多次调用它们。 在app.js中使用套接字连接,并在套接字连接中需要处理程序,将套接字作为参数传递。 请注意,某些属性可能不会与套接字实例一起提供

@leemlwando,如有需要,请打开一个新期刊。

我有一个同样的问题,就是在客户端上进行手动重新连接功能并调用io.destroy();。 在重新连接功能内部,此问题已解决。

非常感谢@leemlwando您的最后评论使我解决了我的问题。

我仍然遇到此错误,是否有任何更新?

我认为这里唯一真正的错误是互联网上充满了糟糕的示例代码,其中socket.on()调用包装在socket.on('connect')处理函数中。 每次套接字重新连接时,处理程序的新实例都会堆叠在现有实例的顶部,这将导致每个事件发生多次调用。 不要这样做:请参阅@KasperTidemann从2012年7月25日起的回复。

也许DrLexO,除了上面提供的代码证明了这个问题。 它没有任何socket.on()包装在任何socket.on('connect')处理函数中。

这些年来,我很惊讶仍然收到有关此错误的通知。 我不知道这是否仍然存在。 我需要再试一次吗?

@KasperTidemann谢谢,它实际上解决了这个问题。

当您无权访问socket时,如何定义事件侦听器_outside_在connect侦听器中?

const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http);

io.on('connect', function(socket) {

  // only now that we are inside the connect callback do we have access to the socket

  socket.on('join', function(room, user) {
  });

  socket.on('add_message', function(room, user) {
  });

  socket.on('disconnect', function(room, user) {
  });
});

人们似乎建议事件侦听器( joinadd_messagedisconnect )应该独立生活,_outside_ connect侦听器,但是如果没有它,怎么可能socket被定义?

io.on('connect', function(socket) {
  // socket is only available here
});

// socket is undefined here

socket.on('join', function(room, user) {
});

socket.on('add_message', function(room, user) {
});

socket.on('disconnect', function(room, user) {
});

有没有其他实例化socket使之可行?

为什么关闭? @ michael-lynch有一个正确的论点

我也想知道@ michael-lynch观点的答案。

socket.io网站示例上的@ DrLex0甚至显示执行以下操作:

io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
  });
});
此页面是否有帮助?
0 / 5 - 0 等级