socket.io在x秒/第一次失败后尝试获取响应时停止重新发出事件

时间:2015-08-21 02:50:29

标签: javascript node.js websocket socket.io

我注意到,只要我的服务器处于脱机状态,并且我将其重新联机,就会收到大量的套接字事件,这些事件在服务器关闭时被触发。 (已经过时的事件)。

有没有办法阻止socket.io在没有收到x秒响应后重新发出事件?

1 个答案:

答案 0 :(得分:22)

当所有其他方法都无法使用开源库时,您将继续研究代码并了解您可以找到的内容。花了一些时间用socket.io源代码...

问题的症结似乎是socket.emit()here的代码:

  if (this.connected) {
    this.packet(packet);
  } else {
    this.sendBuffer.push(packet);
  }

如果套接字未连接,则.emit()发送的所有数据都会缓存在sendBuffer中。然后,当套接字再次连接时,我们会看到:

Socket.prototype.onconnect = function(){
  this.connected = true;
  this.disconnected = false;
  this.emit('connect');
  this.emitBuffered();
};

Socket.prototype.emitBuffered = function(){
  var i;
  for (i = 0; i < this.receiveBuffer.length; i++) {
    emit.apply(this, this.receiveBuffer[i]);
  }
  this.receiveBuffer = [];

  for (i = 0; i < this.sendBuffer.length; i++) {
    this.packet(this.sendBuffer[i]);
  }
  this.sendBuffer = [];
};

因此,这完全解释了为什么它会在连接断开时缓冲所有发送的数据,然后在重新连接时发送所有数据。

现在,关于如何阻止它发送这个缓冲数据,这是一个理论,我将在今晚有更多时间后尝试测试。

两件事看起来像是一个机会。套接字在发送缓冲数据之前通知connect事件,sendBuffer是套接字的公共属性。所以,看起来你可以在客户端代码中执行此操作(在连接时清除缓冲区):

// clear previously buffered data when reconnecting
socket.on('connect', function() {
    socket.sendBuffer = [];
});

我刚试过它,它运作得很好。我有一个客户端套接字,每秒向服务器发送一个增加的计数器消息。我将服务器关闭5秒钟,然后当我在添加此代码之前重新启动服务器时,所有排队的消息都会到达服务器上。没有错过任何计数。

当我在上面添加上面三行代码时,服务器关闭时发送的任何消息都不会发送到服务器(从技术上讲,它们在发送之前会从发送缓冲区中清除)。它有效。

仅供参考,另一种可能性是在未连接套接字时不调用.emit()。因此,您可以创建自己的函数或方法,只有在套接字实际连接时才会尝试.emit(),因此什么都不会进入sendBuffer

Socket.prototype.emitWhenConnected = function(msg, data) {
    if (this.connected) {
        return this.emit(msg, data);
    } else {
        // do nothing?
        return this;
    }
}

或者,更危险的是,您可以覆盖.emit()以使其以这种方式工作(而不是我的建议)。