我要解决一个特殊的问题。在服务器上,我有以下代码...
// Establish a connection with a WebSocket.
io.on("connection", socket => {
setTimeout(sendHeartbeat, 25000);
function sendHeartbeat(){
setTimeout(sendHeartbeat, 25000);
io.sockets.emit("ping", socket.id);
console.log(io.sockets.adapter.rooms);
}
});
正在发生的事情是,我每25秒对所有现有的套接字ping一次客户端,然后发送连接的客户端的套接字ID。
在客户端,我只是在监听结果并将其打印到控制台...
socket.on('ping',function(data) {
console.log(data);
});
我启动服务器并建立连接,在服务器上,我有以下信息...
{ QofufgzXeTqGJcLOAAAA: Room { sockets: { QofufgzXeTqGJcLOAAAA: true }, length: 1 } }
这是正确的,因为只有1个连接,但是在客户端,每隔25秒,控制台将显示如下...
undefined
QofufgzXeTqGJcLOAAAA
不确定undefined
的来源。
我继续让服务器运行,最终套接字断开然后再重新连接(这种情况时不时发生),在这种情况下,应删除旧的套接字并用新的套接字替换,这恰好发生在服务器...
{ o2UFD7iHNxc94bPHAAAB: Room { sockets: { o2UFD7iHNxc94bPHAAAB: true }, length: 1 } }
但是在客户端,每25秒打印以下内容...
undefined
QofufgzXeTqGJcLOAAAA
o2UFD7iHNxc94bPHAAAB
我试图了解为什么旧的插槽没有被移除。每次断开连接时,似乎都添加了一个额外的套接字。我怎样才能解决这个问题?在上面的示例中,应该仅将一个套接字ID打印到控制台。
答案 0 :(得分:0)
您可以将其更改为io.once("connection")
,这意味着每次连接时,它不会添加其他绑定,或者您可以订阅断开连接事件,并在连接中断时取消绑定此事件。我倾向于第二种方法,因为它可以使代码更简洁,以后的wtf时间更少
答案 1 :(得分:0)
对我有用的解决方案是将c("AAA", "BBB", "CCC")
与setInterval
一起使用。之所以要在控制台上打印多个套接字,是因为递归函数从未清除,因此所有实例都异步运行。
我的新解决方案如下...
clearInterval
...然后断开连接,我就会...
// Ping the client to prevent disconnect.
let keepAlive = setInterval(sendHeartbeat, 25000);
function sendHeartbeat(){
io.sockets.emit("ping", socket.id);
console.log(io.sockets.adapter.rooms);
}
这解决了我的问题,现在我只能按预期将1个套接字打印到控制台上。我仍然也可以使用socket.on("disconnect", async () => {
clearInterval(keepAlive);
});
,但是要解决此问题answer可以解决此问题。
基本上, socket.io 需要一段时间才能建立连接,因此undefined
可用于检查是否建立了连接。这将从控制台中删除socket.on('connection', ...)
。