socket.io连接时cookie-session获取失败,无法存储connectionId求助
问题描述
代码示例(server.js)
const express = require("express"); const cookieSession = require("cookie-session"); const socketIo = require("socket.io"); const app = express(); app.use( cookieSession({ name: "session", keys: ["key1", "key2"], }) ); app.use((req, res, next) => { console.log(req.session); next(); }); app.get("/", (req, res) => { res.sendFile("./index.html", { root: __dirname }); }); app.get("/about", (req, res) => { const connectionId = req.session.connectionId; res.send(`About. connectionId: ${connectionId}`); }); const server = app.listen(1234); const io = socketIo(server); io.on("connection", (socket) => { const connectionId = Math.random().toString(36).substring(2); socket.request.session.connectionId = connectionId; // socket.request.session.save(); });
问题:当客户端触发connect事件时,服务器端的socket.request.session返回undefined,无法在cookie-session中设置唯一的connectionId值,请问是什么原因造成的?
原因分析及解决方案
核心原因:Socket.IO默认不会自动继承Express的cookie-session中间件处理逻辑。Express的
cookie-session是挂载在HTTP请求的处理流程中的,但Socket.IO的WebSocket握手请求并没有经过Express的中间件栈,所以socket.request上不会被注入session对象。解决步骤:
- 手动让Socket.IO的握手请求经过Express的
cookie-session中间件处理,可通过复用Express中间件的方式实现:// 先将cookie-session中间件存为变量 const sessionMiddleware = cookieSession({ name: "session", keys: ["key1", "key2"], }); // 给Express挂载中间件 app.use(sessionMiddleware); // 给Socket.IO挂载中间件,让握手请求经过session处理 io.use((socket, next) => { sessionMiddleware(socket.request, {}, next); }); - 恢复注释掉的
save()方法,修改session后必须调用该方法才能将变更持久化到cookie中:socket.request.session.save();
- 手动让Socket.IO的握手请求经过Express的
内容的提问来源于stack exchange,提问作者Данияр Булдаков
相关产品推荐
相关产品推荐

