Nodejs 使用express和socket.io时,如何在socket中获得控制器中赋值的session

Nodejs 使用express和socket.io时,如何在socket中获得控制器中赋值的session

控制器部分代码:req.session.username =****; app.js部分代码:io.of(/chat).on(connection,function(socket){ //获得req.session.username的值 }) 请问怎么获得到

8 回复

在使用 Node.js 的 Express 和 Socket.IO 时,获取通过 HTTP 请求设置的 session 数据是一个常见的需求。通常情况下,Express 会管理 session 数据,而 Socket.IO 则处理实时通信。为了在 Socket.IO 中访问这些 session 数据,你需要确保 session 数据能够在两个框架之间共享。

下面是如何实现这一目标的步骤和示例代码:

步骤

  1. 配置 Express 和 Session 中间件:首先,确保你的 Express 应用正确地设置了 session 中间件。
  2. 将 session 存储在全局变量或 Redis 等共享存储中:由于 Express 和 Socket.IO 运行在不同的上下文中,你需要一种方法来共享 session 数据。一种简单的方法是将 session 存储在一个全局对象中,或者使用 Redis 等共享存储。
  3. Socket.IO 中读取 session 数据:通过 Socket.IO 的连接事件,你可以从全局对象或共享存储中读取 session 数据。

示例代码

app.js

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const session = require('express-session');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

// 配置 session
app.use(session({
    secret: 'your_secret_key',
    resave: false,
    saveUninitialized: true
}));

// 全局存储 session(仅用于演示)
global.sessions = {};

// 控制器逻辑
app.get('/set-session', (req, res) => {
    req.session.username = 'JohnDoe';
    res.send('Session set!');
});

// Socket.IO 监听连接
io.on('connection', (socket) => {
    const sessionId = socket.request.sessionID;
    
    // 从全局存储中获取 session
    const sessionData = global.sessions[sessionId];
    
    if (sessionData && sessionData.username) {
        console.log(`Username from session: ${sessionData.username}`);
    } else {
        console.log('No session data found.');
    }
});

server.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释

  1. Session 配置:使用 express-session 中间件配置 session。
  2. 全局存储:我们将 session 数据存储在全局对象 global.sessions 中。实际生产环境中,建议使用 Redis 或其他共享存储。
  3. Socket.IO 连接处理:当客户端连接时,我们通过 socket.request.sessionID 获取 session ID,并从全局存储中查找对应的 session 数据。

这种方法可以让你在 Socket.IO 中访问由 Express 设置的 session 数据。请注意,对于更复杂的场景,推荐使用 Redis 等共享存储来管理 session 数据,以确保数据的一致性和可靠性。


目前还没有找到方法,可以直接在服务器上获取session值的方法

不过话要说话来,因为你刷新一次页面,都会进行一次socket的连接

那么当客户端连接服务器的时候,都会触发socket.io的connection事件

你可以把你session中的值,赋值给一个javascript变量,然后连接的时候会以json格式发送到

服务器,这样你在代码里就可以取到当前session的值了

但我想做的是:“用户”在控制器渲染的页面中提交用户的名字给app.js,然后app.js中分发这个名字给所有的人,按你所说的话,用户就可以自己随意指定自己的名字了。我实际的应用场景是:在聊天室中,用户发一个消息,其它人会看到是“谁”发的。是不是我这样做有问题呢?

据说牛人很多,咋没有能回答这么常见问题的人儿捏?

socket.io入门 你看看这篇能不能解决你的问题?

io.set(‘authorization’,callback)

一句话,好帖,我今天也在困扰这个,一楼的方法不错

在Node.js中使用Express和Socket.IO时,可以通过中间件将Session与Socket关联起来,从而在Socket.IO的连接中访问Express的Session。

以下是如何实现这一点的示例代码:

  1. 首先确保你已经安装了必要的包:

    npm install express express-session socket.io
    
  2. 在你的app.js文件中,添加如下代码以设置Session,并将Session挂载到Socket上:

const express = require('express');
const session = require('express-session');
const http = require('http');
const socketIo = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

// 设置Session中间件
app.use(session({
  secret: 'your_secret_key',
  resave: false,
  saveUninitialized: true,
}));

// 存储用户Session
app.get('/set-session', (req, res) => {
  req.session.username = 'testUser';
  res.send('Session set');
});

// Socket.IO连接处理
io.on('connection', (socket) => {
  const sessionId = socket.request.sessionID;

  // 通过Session ID从存储中获取Session对象
  const sessionStore = app.get('sessionStore');
  sessionStore.get(sessionId, (err, session) => {
    if (err || !session) {
      console.error('Failed to get session:', err);
      return;
    }

    // 现在你可以访问session对象中的数据
    console.log('Username from session:', session.username);

    // 向客户端发送用户名
    socket.emit('username', session.username);
  });
});

server.listen(3000, () => {
  console.log('Server is running on port 3000');
});

解释

  • 设置Session:我们首先使用express-session中间件来设置Session。
  • 设置Session Store:我们需要一个Session存储来保存Session数据。通常情况下,Express会使用默认的内存存储,但你也可以使用其他持久化存储(如Redis)。
  • 获取Session:在Socket.IO连接时,我们通过socket.request.sessionID获取Session ID,然后使用Session存储来获取对应的Session对象。
  • 访问Session数据:一旦获取了Session对象,就可以访问其中的数据,比如session.username

这样,你就可以在Socket.IO连接中访问到通过Express中间件设置的Session数据了。

回到顶部