Node.js Socket.io 设置多个连接
Posted
技术标签:
【中文标题】Node.js Socket.io 设置多个连接【英文标题】:Node.js Socket.io sets up multiple connections 【发布时间】:2018-02-21 10:53:17 【问题描述】:我正在创建一个使用 passport.js 进行身份验证的简单 socket.io 聊天。但是每次用户注销并登录时,旧的套接字连接都会重新连接。这会导致问题,因为现在有两个活动连接到一个页面。所以我想要做的是当用户导航到“/logout”时结束当前连接。
var socketNotLoaded = true;
var socket;
app.get('/', function(req, res)
if (req.isAuthenticated())
if(socketNotLoaded) //is true when new connection is required
require("./socket")(io,req.user) //runs the socket.io script
socketNotLoaded = false;
res.render('index', pug.get(req.user));
else
res.render('notloggedin', pug.get());
)
app.get('/logout', function(req, res)
socketNotLoaded = true;
req.logout();
res.redirect('/');
)
我正在使用
socket.io: 2.0.3 护照:0.4.0 护照本地:1.0.0 快递:4.15.4 快速会话:1.15.5 cookie 解析器:1.4.3 正文解析器:1.17.2【问题讨论】:
显然您的网页中有客户端代码在您注销并重新连接后重新连接。这很可能是问题所在。另外,您的代码似乎只为一位用户设计。如果if(socketNoLoaded)
调用使用模块级变量来决定是否使用req.user
初始化socket.io。那是没有意义的。当第二个用户访问您的网站时,您期望会发生什么?还是第三个用户?
哦,我明白了。我应该如何解决这个问题?
老实说,我不明白你在做什么。在我看来,您当前的设计存在根本缺陷。每个用户的状态需要在您的会话中,而不是在模块级变量中。 socket.io 服务器应该在服务器启动时初始化,同时你的 web 服务器也被初始化。它应该始终在运行,并且不应使用任何每个用户的状态进行初始化。您不会为每个用户创建一个新的 socket.io 服务器,您有一个所有用户都使用的 socket.io 服务器(就像您的 Web 服务器一样)。
谢谢,现在更有意义了。但是我如何安全地向 socket.io 提供活跃用户的详细信息?
我不知道“提供活跃用户详细信息”是什么意思?什么是“活跃用户详细信息”,为什么要将它们提供给 socket.io 服务器?
【参考方案1】:
在客户端,当用户想要注销时,您可以执行socket.emit('exit');
,然后在服务器端有一个监听器,如下所示:
socket.on('exit', function()
socket.disconnect();
);
这将断开客户端与 Socket.io 的连接。您还可以在服务器端创建一个将用户名映射到 Socket.io 套接字 ID 的对象,并执行检查以查看该用户是否已经存在。如果是这样,那么您可以在服务器端断开该套接字 ID。理想情况下,客户端应在用户注销时向服务器发送disconnect
。像这样的:
$('#logout').click( function()
socket.disconnect();
window.location = "/logout";
);
【讨论】:
我已经尝试过了,但是您第二次登录时仍然有两个实时连接。 客户端可以随时断开连接。它不需要向服务器发送消息来告诉服务器断开连接。另外,OP 的代码在注销后重定向,因此当前的套接字连接无论如何都会在重定向时被终止。 正如@jfriend00 所说,您可以让客户端断开连接。我们不知道您是如何做到这一点的,因为您没有提供您的客户端代码。 在客户端发生的所有事情都是用户被重定向到“/logout”并进行初始连接。 var socket = io.connect(window.location.href.split("/")[2]); 好吧,假设注销类似于单击按钮,为该按钮创建一个事件侦听器,然后调用socket.disconnect()
,然后执行重定向window.location = "/logout";
以上是关于Node.js Socket.io 设置多个连接的主要内容,如果未能解决你的问题,请参考以下文章
Socket.io node.js,如何避免记录连接时间或考虑页面刷新/多个套接字?
在重新连接、socket.io、node.js 时重用套接字 id