我目前正在使用node.js创建一个web应用程序。 当用户进入侧面时,会建立通过socket.io的连接。 我想阻止多个连接。用户应该只能连接一次,如果他在另一个窗口中打开页面,我想显示一条消息,如“已经连接,请关闭所有其他标签”,或类似的东西。
为此,我使用“express-session”为用户创建会话。使用以下代码与socket.io共享此会话。 我不确定,如果我正确地做到了。我查看了一些教程,他们都以类似的方式分享会话。但有时,我认为,当我在socket.io-session中更改并保存一个值时会覆盖会话数据。
var sessionStoreClient = Redis.createClient({
port: DBs.sessionStore_redis.port,
host: DBs.sessionStore_redis.host,
password: DBs.sessionStore_redis.password,
db: DBs.sessionStore_redis.database
});
var sessionStore = new RedisStore({
unset: "destroy",
client: sessionStoreClient
});
var sessionInstance = expressSession(
{
key: sessionsKey,
store: sessionStore,
secret: sessionsSecret,
unset: "destroy"
}
);
app.use(sessionInstance);
app.use(passport.initialize());
app.use(passport.session());
与socket.io共享会话,我正在使用以下代码
var passportSocketIo = function(app,sessionInstance, passport){
return function(socket, next){
var req = socket.request;
sessionInstance(req,req.res,
function () {
if (!req.session) {
return next(new Error("Not authorized"), false);
}
req.updateSessionValue = function (propertyName, propertyValue, callback) {
if(!req.session){
console.log("unauthorized session modification");
return;
}
req.session.reload(()=>{
req.session[propertyName] = propertyValue;
req.session.save();
if(callback)
callback(propertyName, propertyValue,req.session);
});
};
if(req.session.passport && req.session.passport.user) {
passport.deserializeUser(req.session.passport.user, req, function (err, user) {
req.user = user;
req.user.logged_in = true;
return next(null, true);
});
}else {
return next(null, true);
}
}
);
};
};
var nsp = io.of(Packages.NAMESPACES.LOBBY);
nsp .use(options.sessionMiddleware);
在socket.io-listeners内部编辑会话的值,我使用的函数在上面的代码中设置为请求。
_onConnectionReceived(socket) {
socket.request.updateSessionValue("isConnected",true);
}
当用户从套接字断开连接时:
_onDisconnect(socket) {
socket.request.updateSessionValue("isConnected",false);
}
对于登录和身份验证,我目前正在使用passport.js。
当用户退出时,他被重定向到同一页面,但被重定向到“guest”--user。对于loggin out,我使用以下代码:
router.get('/logout',function(req, res,next){
req.logout();
req.session.destroy(
function (err) {
res.render('logout',{});
}
);
});
问题是,在会话被销毁并且用户被重定向之后,会触发socket.io disconnect事件。即使在“onDisconnected”事件监听器内部重新加载之后,会话似乎仍然存在,在修改该值之后,会话似乎以某种方式重新创建。还有感觉,会话值有时只是被覆盖 - 我还没有找到原因。
任何人都可以解释我做错了什么,或者是否有更好的方式来分享和修改会话?会话的“重新加载”功能是否真的从sessionStore重新加载其数据?
另一种方法可能是将会话/用户ID保存在一个哈希集中,并检查是否已打开连接(不将其保存在自己的会话中),但我很好奇,如果我的方法是正确的,因为我无论如何都需要分享和修改会议。