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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9708604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 15:20:00  来源:igfitidea点击:

NodeJS + Socket.io connections dropping/reconnecting?

node.jssocket.io

提问by majic bunnie

In production, I have a game which uses connection-local variables to hold game state. However I notice that if I idle for a certain time on the connection, it disconnects and reconnects which loses the current state. During my tests on a local host, I never noticed this behavior. Is this the norm behavior for socket connections or is something else causing the connections to drop.

在生产中,我有一个使用连接局部变量来保存游戏状态的游戏。但是我注意到,如果我在连接上空闲了一段时间,它会断开连接并重新连接,从而失去当前状态。在本地主机上进行测试时,我从未注意到这种行为。这是套接字连接的规范行为还是导致连接断开的其他原因。

If it is a normal behavior how is this typically handled? Should connection values be stored globally so they can be restored should a user drop/reconnect?

如果这是正常行为,通常如何处理?连接值是否应该全局存储,以便在用户断开/重新连接时可以恢复它们?

回答by Moox

Your problem is around socket timeouts. If there's no activity on a certain socket, socket.io will close it automatically.

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

An easy (and hackish) fix is to send a heartbeat to the connected client to create activity and stop the socket from timing out.

一个简单(和hackish)的解决方法是向连接的客户端发送心跳以创建活动并阻止套接字超时。

Server:

服务器:

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);

Client:

客户:

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

More Information:

更多信息:

You can get more information on configuring socket.io here.

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

EDIT: Mark commented that if the user does lose the connection (connection drops on his end because of internet troubles), you should be able to restore the user to his last state.

编辑:Mark 评论说,如果用户确实失去了连接(由于互联网问题,他的一端连接断开),您应该能够将用户恢复到他的最后状态。

To do that, the best way would be to use a already widely used method for storing user data, cookies and sessions.

为此,最好的方法是使用一种已经广泛使用的方法来存储用户数据、cookie 和会话。

An extremely well done tutorial on how to do this located here. Although he uses express to set cookies, you can do this using anything (I do it using rails). Using this method, you can store the user data in a cookie and fetch it during the handshake. From there you can just access the data using socket.handshake.data.

关于如何执行此操作的非常出色的教程位于此处。尽管他使用 express 来设置 cookie,但您可以使用任何东西来做到这一点(我使用 Rails 来做到这一点)。使用此方法,您可以将用户数据存储在 cookie 中并在握手期间获取它。从那里您可以使用socket.handshake.data.

回答by Mark

What you need to do is create or identify the session per (re-) connection. You may reduce the number of reconnections per Moox's answer above but it is still not failsafe - e.g. a user loses wifi connection for a bit, etc. In other words - maintain user metadata per session and not per socket, and expect occasional disconnects and reconnects.

您需要做的是创建或识别每个(重新)连接的会话。您可以根据上面 Moox 的回答减少重新连接的次数,但它仍然不是故障安全的 - 例如,用户失去了一点 wifi 连接等。换句话说 - 维护每个会话而不是每个套接字的用户元数据,并期望偶尔断开连接和重新连接.