Nodejs socket.io断开后自动重连上,收到的消息就重复了,断几次就会收到多少重复消息,怎么回事?
Nodejs socket.io断开后自动重连上,收到的消息就重复了,断几次就会收到多少重复消息,怎么回事?
socket.io断开后自动重连上,收到的消息就重复了,断几次就会收到多少重复消息,怎么回事?为何不能自动销毁掉。 该如何解决
当使用 socket.io
进行实时通信时,如果客户端与服务器之间的连接断开并重新连接,可能会导致消息重复接收的问题。这是因为每次重新连接时,客户端会重新加入所有现有的事件监听器,而这些监听器在之前的连接中已经被注册过。因此,每当有新的消息到达时,每个重新连接的客户端都会触发一次事件处理函数,从而导致消息重复。
解决方案
一种有效的解决方案是在每次重新连接时清除旧的事件监听器,并重新注册它们。这可以通过在事件监听器内部使用 once
方法来实现,once
方法确保事件只被触发一次。
示例代码
const io = require('socket.io')(server, {
transports: ['polling', 'websocket']
});
io.on('connection', function(socket) {
console.log('New client connected');
// 清除旧的事件监听器
socket.removeAllListeners();
// 使用 once 方法确保事件只被触发一次
socket.once('message', function(msg) {
console.log('Message received:', msg);
// 处理消息
});
// 当客户端断开连接时
socket.on('disconnect', function() {
console.log('Client disconnected');
});
});
解释
- 清除旧的事件监听器:通过调用
socket.removeAllListeners()
,我们可以确保在每次重新连接时清除所有旧的事件监听器。 - 使用
once
方法:once
方法用于确保事件只被触发一次。这意味着即使客户端重新连接多次,消息也只会被处理一次。 - 处理
disconnect
事件:我们还需要监听disconnect
事件,以便在客户端断开连接时进行适当的清理工作。
通过这种方式,可以有效避免由于客户端多次重新连接而导致的消息重复问题。
已经搞定 原因: 错误写法: var socket = io.connect(); socket.on(‘connect’, function () { socket.on(‘message’, function(message) { }); socket.on(‘disconnect’, function() { }); }); 正确写法: var socket = io.connect(); socket.on(‘connect’, function () { }); socket.on(‘message’, function(message) { }); socket.on(‘disconnect’, function() { });
thank you~~
楼主的代码是client的吗? 为什么我没写connect和discontect 也会这样呢? 手工discontect重复链接不理想啊!求解救。。
我勒个去,找到问题了 因为之前不知道在哪里看的,加了下面这个代码 socketio.socket.on(‘error’, function(){ socketio.socket.connect(); });
发现IE下此问题还存在 好像在github里看到,说这个是bug,不知道修复没。。。
socket.on('connect', function () {
try {
console.log('connect success');
} catch (e) {
}
var curTime = new Date().getTime();
Ws.reConnNum = 1;
if (Ws.lastTime && (curTime - Ws.lastTime <= 5000)) {
Ws.lastTime = curTime;
return;
}
Ws.lastTime = curTime;
socket.emit('init', {id:speek.selfid, nation:speek.selfgroup});
});
socket.on('message', function (message, callback) {
try {
console.log('message');
} catch (e) {
}
});
socket.on('disconnect', function () {
try {
console.log('disconnect');
} catch (e) {
}
});
socket.on('connect_failed', function () {
try {
console.log('connect_failed');
} catch (e) {
}
});
socket.on('error', function () {
try {
console.log('error');
} catch (e) {
}
});
socket.on('reconnect_failed', function () {
try {
console.log('reconnect_failed');
} catch (e) {
}
});
socket.on('reconnect', function () {
try {
console.log('reconnect');
} catch (e) {
}
});
socket.on('reconnecting', function () {
if (Ws.reConnNum == 3) {
setTimeout(function () {
if (Ws.reConnNum == 4) {
Ws.showDisWin();
}
}, 5000);
}
Ws.reConnNum++;
try {
console.log('reconnecting');
} catch (e) {
}
});
我也遇到楼主的问题了,不知道我这样写是否有问题???
谢谢楼主。也是这样解决的。
那
socket.on('connect', function () {
});
里应该是什么代码
请问这个问题最终怎么解决的,本菜鸟初次用,也遇到这个问题,谢谢各位大神
请问这个问题最终怎么解决的,本菜鸟初次用,也遇到这个问题,谢谢各位大神
在使用 Socket.IO 时,如果客户端与服务器断开连接后重新连接,可能会导致事件监听器多次注册,从而引发重复接收消息的问题。这是因为每次连接成功后,都会重新绑定事件监听器,而之前的监听器并未被销毁。
解决方法
为了解决这个问题,我们需要确保在重新连接之前移除所有旧的事件监听器。可以通过以下几种方式实现:
- 在每次重新连接前清除事件监听器:
- 可以通过一个标志位来检查是否已经绑定过监听器,在绑定之前检查该标志位。
- 或者在断开连接时清除事件监听器。
示例代码
const io = require('socket.io')(server);
let isListenerBound = false;
function bindListeners(socket) {
if (isListenerBound) return;
socket.on('message', (data) => {
console.log('Received:', data);
});
isListenerBound = true;
}
io.on('connection', (socket) => {
console.log('A user connected');
bindListeners(socket);
socket.on('disconnect', () => {
console.log('User disconnected');
isListenerBound = false; // 在断开连接时重置标志位
});
});
在这个示例中,我们使用了一个 isListenerBound
变量来追踪是否已经绑定了监听器。当客户端连接时,我们检查这个变量,如果未绑定,则绑定事件监听器,并将标志位置为 true
。当客户端断开连接时,我们将标志位置为 false
,这样下次连接时可以重新绑定监听器。
总结
通过这种方式,我们可以避免在客户端断开连接并重新连接后多次接收消息的问题。这种方法简单有效,适用于大多数场景。