【发布时间】:2012-03-14 19:12:59
【问题描述】:
在生产中,我有一个使用连接局部变量来保存游戏状态的游戏。但是我注意到,如果我在连接上闲置一段时间,它会断开连接并重新连接,从而丢失当前状态。在本地主机上进行测试期间,我从未注意到这种行为。这是套接字连接的规范行为还是导致连接断开的其他原因。
如果这是正常行为,通常如何处理?连接值是否应该全局存储,以便在用户断开/重新连接时可以恢复?
【问题讨论】:
在生产中,我有一个使用连接局部变量来保存游戏状态的游戏。但是我注意到,如果我在连接上闲置一段时间,它会断开连接并重新连接,从而丢失当前状态。在本地主机上进行测试期间,我从未注意到这种行为。这是套接字连接的规范行为还是导致连接断开的其他原因。
如果这是正常行为,通常如何处理?连接值是否应该全局存储,以便在用户断开/重新连接时可以恢复?
【问题讨论】:
您的问题与套接字超时有关。如果某个socket没有活动,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的信息here.
编辑:马克评论说,如果用户确实失去了连接(由于互联网问题而导致连接中断),您应该能够将用户恢复到他的最后状态。
为此,最好的方法是使用已经广泛使用的方法来存储用户数据、cookie 和会话。
关于如何做到这一点的非常出色的教程located here。尽管他使用 express 来设置 cookie,但您可以使用任何东西来执行此操作(我使用 rails 来执行此操作)。使用此方法,您可以将用户数据存储在 cookie 中并在握手期间获取它。从那里您可以使用socket.handshake.data 访问数据。
【讨论】:
pingTimeout 和 'pingInterval' 分别设置为 60 秒。 25 秒。
您需要做的是创建或识别每个(重新)连接的会话。您可以根据上面 Moox 的回答减少重新连接的次数,但它仍然不是故障安全的 - 例如用户失去了 wifi 连接,等等。换句话说 - 维护每个会话而不是每个套接字的用户元数据,并期望偶尔断开连接和重新连接。
【讨论】: