我注意到,每当我的服务器脱机时,只要我将其切换回在线状态,它都会收到大量的套接字事件,这些事件是在服务器关闭时触发的。 (现在已过时的事件)。
在x秒钟未收到响应之后,是否有办法阻止socket.io重新发送事件?
最佳答案
当开源库的所有其他功能都失败时,您可以继续研究代码,然后找出可以解决的问题。在花了一些时间使用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
是套接字的公共(public)属性。因此,看起来您可以在客户端代码中执行此操作(在连接时清除缓冲区):// 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()
使其以这种方式工作(不是我的建议)。