NodeJS + Socket.io连接会断开/重新连接吗?

14
在生产环境中,我有一个游戏使用连接本地变量来保存游戏状态。然而,我注意到如果我在连接上闲置一段时间,它会断开并重新连接,从而丢失当前状态。在我的本地主机上进行测试时,我从未注意到这种行为。这是否是套接字连接的正常行为,还是其他因素导致连接断开。
如果这是正常行为,通常应该如何处理?连接值应该全局存储,以便在用户断开/重新连接时可以恢复吗?
2个回答

30

你的问题与套接字超时有关。如果某个套接字上没有任何活动,socket.io 将自动关闭它。

一个简单(但不太正规)的解决方法是向已连接的客户端发送心跳以创建活动并防止套接字超时。

服务器:

function sendHeartbeat(){
    setTimeout(sendHeartbeat, 8000);
    io.sockets.emit('ping', { beat : 1 });
}

io.sockets.on('connection', function (socket) {
    socket.on('pong', function(data){
        console.log("Pong received from client");
    });
}

setTimeout(sendHeartbeat, 8000);

客户端:

socket.on('ping', function(data){
      socket.emit('pong', {beat: 1});
    });

更多信息:

您可以在此处获取有关配置socket.io的更多信息:这里。

编辑:Mark评论说,如果用户失去连接(因为互联网问题导致连接中断),您应该能够将用户恢复到上次的状态。

为了达到这个目的,最好使用存储用户数据的广泛使用的方法之一,即Cookie和Session。一个非常好的教程在这里,虽然他使用Express来设置Cookie,但您可以使用任何东西来实现它(我使用Rails)。使用此方法,您可以将用户数据存储在Cookie中,并在握手期间获取它。从那里,您只需使用socket.handshake.data访问数据即可。


2
这是一个聪明的解决方案,但它会让服务器和客户端忙于乒乓球游戏 :-( 有其他的解决方案吗? - Ketan Parmar
3
现在,socket.io已经自动设置了pingTimeoutpingInterval分别为60秒和25秒。 - Pauloco

0
你需要做的是每次重新连接时创建或识别会话。你可以按照Moox在上面的回答来减少重新连接的数量,但这仍然不是万无一失的 - 例如,用户暂时失去了Wi-Fi连接等。换句话说 - 每个会话保持用户元数据而不是套接字,并期望偶尔的断开和重新连接。

你说得对,我编辑了我的问题以考虑到那一点。 - Moox
我在我的应用程序中所做的是按会话维护用户数据,而不是socket.io连接,并根据用户连接/断开连接管理会话。顺便说一句,这引发了整个问题,即为什么socket.io包括每个套接字数据 - 我认为这个功能在socket.io操作方式上并不真正“兼容”。尝试使用它并放弃了它,因为经常出现断开/重新连接的情况。 - Mark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接