首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何与Socket.IO 1.x和Express4.x共享会话?

如何与Socket.IO 1.x和Express4.x共享会话?
EN

Stack Overflow用户
提问于 2014-08-28 00:43:54
回答 6查看 53.4K关注 0票数 97

如何与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'));
        }
    });
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 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);
票数 227
EN

Stack Overflow用户

发布于 2014-09-24 00:20:27

就在一个半月前,我处理了同样的问题,后来我写了一个关于这个主题的广泛的blog post,它与GitHub上的一个完全工作的demo app一起使用。该解决方案依赖于express-sessioncookie-parserconnect-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上查看它,你可以对它做任何你想做的事情。

票数 6
EN

Stack Overflow用户

发布于 2015-12-05 23:44:15

express-socket.io-session

是针对您的问题的现成解决方案。通常,在socket.io端创建的会话与在express.js中创建的会话具有不同的sid

在知道这一事实之前,当我通过它来寻找解决方案时,我发现了一些奇怪的事情。从express.js实例创建的会话可以在socket.io端访问,但对于相反的情况则不可能。很快,我开始意识到我必须通过管理sid来解决这个问题。但是,已经有一个解决这个问题的方案。它有很好的文档记录,可以完成工作。希望能有所帮助

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25532692

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档