如何与Socket.io 1.0和Express4.x共享会话?我使用的是Redis商店,但我相信这无关紧要。我知道我必须使用中间件来查看cookie和获取会话,但不知道如何使用。我找了找,但找不到任何工作
var RedisStore = connectRedis(expressSession);
var session = expressSession({
store: new RedisStore({
client: redisClient
}),
secret: mysecret,
saveUninitialized: true,
resave: true
});
app.use(session);
io.use(function(socket, next) {
var handshake = socket.handshake;
if (handshake.headers.cookie) {
var str = handshake.headers.cookie;
next();
} else {
next(new Error('Missing Cookies'));
}
});
发布于 2014-09-02 16:04:33
解决方案出奇的简单。它只是没有很好的记录。也可以使用express会话中间件作为Socket.IO中间件,只需使用如下小型适配器:
sio.use(function(socket, next) {
sessionMiddleware(socket.request, socket.request.res, next);
});
下面是express 4.x、Socket.IO 1.x和Redis的完整示例:
var express = require("express");
var Server = require("http").Server;
var session = require("express-session");
var RedisStore = require("connect-redis")(session);
var app = express();
var server = Server(app);
var sio = require("socket.io")(server);
var sessionMiddleware = session({
store: new RedisStore({}), // XXX redis server config
secret: "keyboard cat",
});
sio.use(function(socket, next) {
sessionMiddleware(socket.request, socket.request.res || {}, next);
});
app.use(sessionMiddleware);
app.get("/", function(req, res){
req.session // Session object in a normal request
});
sio.sockets.on("connection", function(socket) {
socket.request.session // Now it's available from Socket.IO sockets too! Win!
});
server.listen(8080);
发布于 2014-09-24 00:20:27
就在一个半月前,我处理了同样的问题,后来我写了一个关于这个主题的广泛的blog post,它与GitHub上的一个完全工作的demo app一起使用。该解决方案依赖于express-session、cookie-parser和connect-redis节点模块来整合所有内容。它允许您从REST和Sockets上下文访问和修改会话,这非常有用。
两个关键部分是中间件设置:
app.use(cookieParser(config.sessionSecret));
app.use(session({
store: redisStore,
key: config.sessionCookieKey,
secret: config.sessionSecret,
resave: true,
saveUninitialized: true
}));
...and SocketIO服务器设置:
ioServer.use(function (socket, next) {
var parseCookie = cookieParser(config.sessionSecret);
var handshake = socket.request;
parseCookie(handshake, null, function (err, data) {
sessionService.get(handshake, function (err, session) {
if (err)
next(new Error(err.message));
if (!session)
next(new Error("Not authorized"));
handshake.session = session;
next();
});
});
});
它们与我制作的一个简单的sessionService模块配合使用,该模块允许您对会话执行一些基本操作,代码如下所示:
var config = require('../config');
var redisClient = null;
var redisStore = null;
var self = module.exports = {
initializeRedis: function (client, store) {
redisClient = client;
redisStore = store;
},
getSessionId: function (handshake) {
return handshake.signedCookies[config.sessionCookieKey];
},
get: function (handshake, callback) {
var sessionId = self.getSessionId(handshake);
self.getSessionBySessionID(sessionId, function (err, session) {
if (err) callback(err);
if (callback != undefined)
callback(null, session);
});
},
getSessionBySessionID: function (sessionId, callback) {
redisStore.load(sessionId, function (err, session) {
if (err) callback(err);
if (callback != undefined)
callback(null, session);
});
},
getUserName: function (handshake, callback) {
self.get(handshake, function (err, session) {
if (err) callback(err);
if (session)
callback(null, session.userName);
else
callback(null);
});
},
updateSession: function (session, callback) {
try {
session.reload(function () {
session.touch().save();
callback(null, session);
});
}
catch (err) {
callback(err);
}
},
setSessionProperty: function (session, propertyName, propertyValue, callback) {
session[propertyName] = propertyValue;
self.updateSession(session, callback);
}
};
因为有比这更多的代码(比如初始化模块,在客户端和服务器端使用套接字和REST调用),我不会在这里粘贴所有的代码,你可以在GitHub上查看它,你可以对它做任何你想做的事情。
发布于 2015-12-05 23:44:15
是针对您的问题的现成解决方案。通常,在socket.io端创建的会话与在express.js中创建的会话具有不同的sid
在知道这一事实之前,当我通过它来寻找解决方案时,我发现了一些奇怪的事情。从express.js实例创建的会话可以在socket.io端访问,但对于相反的情况则不可能。很快,我开始意识到我必须通过管理sid来解决这个问题。但是,已经有一个解决这个问题的方案。它有很好的文档记录,可以完成工作。希望能有所帮助
https://stackoverflow.com/questions/25532692
复制相似问题