Nodejs中socket.io问题

Nodejs中socket.io问题

io.set(‘authorization’, function(handshakeData, accept) { 设置了session 但是 io.sockets.on(‘connection’, function (socket) { 这里的soket的handshake里面没有session信息

为什么?大神帮忙下

6 回复

Node.js 中 socket.io 问题

在使用 socket.io 的过程中,有时会遇到在 socket.handshake 中无法获取到 session 信息的情况。这通常是由于 socket.io 在处理连接时并没有自动将 HTTP session 传递给 WebSocket 连接。因此,你需要手动将 session 信息传递给 WebSocket 连接。

示例代码

首先,确保你已经安装了所需的依赖库:

npm install express socket.io express-session

接下来,编写一个简单的服务器端代码来演示如何将 session 信息传递给 WebSocket 连接:

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
}));

// 设置授权逻辑
io.use((socket, next) => {
    const handshake = socket.request;
    if (!handshake.session) {
        return next(new Error('Session not found'));
    }
    socket.handshake.session = handshake.session;
    return next();
});

io.on('connection', (socket) => {
    console.log('A user connected:', socket.id);

    // 现在你可以访问 socket.handshake.session
    console.log(socket.handshake.session);

    socket.on('disconnect', () => {
        console.log('User disconnected:', socket.id);
    });
});

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

解释

  1. 配置 Session: 使用 express-session 来配置 session。这里我们定义了一个 session 中间件,并设置了 secretresavesaveUninitialized 参数。

  2. 设置授权逻辑: 使用 io.use() 方法来设置授权逻辑。在这个例子中,我们将 session 从 socket.request 中提取出来并赋值给 socket.handshake.session

  3. 连接事件: 当客户端连接时,可以在 io.on('connection') 事件中访问 socket.handshake.session,从而获取到 session 信息。

通过这种方式,你可以在 WebSocket 连接中正确地获取到 session 信息。


你应该要用io.get(‘authorization’)才能获得把

不是应该socket去set和get吗

//服务端 var io = require(‘socket.io’).listen(80);   io.sockets.on(‘connection’, function (socket) {     socket.on(‘set nickname’, function (name) {         socket.set(‘nickname’, name, function () { socket.emit(‘ready’); });     });       socket.on(‘msg’, function () {         socket.get(‘nickname’, function (err, name) {             console.log('Chat message by ', name);         });     }); });

//客户端 <script> var socket = io.connect(‘http://localhost’);   socket.on(‘connect’, function () {     socket.emit(‘set nickname’, confirm(‘What is your nickname?’));     socket.on(‘ready’, function () {         console.log(‘Connected !’);         socket.emit(‘msg’, confirm(‘What is your message?’));     }); }); </script>

你那个实现应该是0.x里面可以用。

你是用的socket.io最新的1.x版本吧,这个版本确实不能在handshake里面存自定义数据了。你可以写一个专门的函数,每次响应事件的时候(connection、disconnect等)从handshake.headers.cookie去获取Session ID,再从session store里面获取对应的session。

在使用 Socket.IO 时,io.set('authorization', ...) 方法用于自定义连接授权逻辑。如果你希望在 sockethandshake 对象中获取到 session 信息,你需要确保在授权函数中正确地设置这些信息。

解释

  1. 授权函数 (io.set('authorization')):

    • 这个函数会在客户端发起连接请求时被调用。
    • 它允许你在客户端连接之前进行一些自定义验证或设置。
  2. handshake 对象:

    • 这个对象包含了客户端发起连接请求时发送的数据,包括查询参数、HTTP 头等。
    • 如果你在授权函数中设置了某些数据(如 session 信息),它们会被包含在 handshake 对象中。
  3. Socket 事件 (io.sockets.on('connection', ...))

    • 当客户端成功连接后,Socket.IO 会触发 connection 事件。
    • 在该事件的回调函数中,你可以通过 socket.handshake 访问到 handshake 对象。

示例代码

假设你想在授权函数中设置一个自定义的 session 信息,并在 connection 事件的回调函数中访问它:

const io = require('socket.io')(server);

// 自定义授权函数
io.set('authorization', function(handshakeData, accept) {
    // 假设你从客户端请求中获取到了 session ID
    const sessionId = handshakeData.query.sessionId;
    
    // 你可以在这里设置 session 信息或其他自定义数据
    handshakeData.myCustomSession = { id: sessionId };
    
    // 继续接受连接
    accept(null, true);
});

// 监听连接事件
io.sockets.on('connection', function(socket) {
    // 访问 handshake 对象中的自定义数据
    console.log(socket.handshake.myCustomSession); // 输出: { id: 'some-session-id' }
    
    // 其他逻辑
});

注意事项

  • 确保客户端在连接时正确地传递了 sessionId 或其他必要的数据。
  • 如果你需要更复杂的 session 管理(例如与数据库交互),可以考虑使用中间件来处理这些逻辑。
  • 在实际项目中,建议使用成熟的库(如 express-socket.io-session)来管理 session 数据。

希望这能帮助你解决你的问题!

回到顶部