Nodejs大神帮忙看看下面一段代码有什么问题? socket.handshake.session为什么是undefined

Nodejs大神帮忙看看下面一段代码有什么问题? socket.handshake.session为什么是undefined

io.set(‘authorization’, function(handshakeData, accept) {
handshakeData.cookie = Cookie.parse(handshakeData.headers.cookie);
var connectSid = handshakeData.cookie[‘connect.sid’];
connectSid = cookieParser(connectSid, ‘technode’);
if (connectSid) {
sessionStore.get(connectSid, function(error, session) {
if (error) {
accept(error.message, false);
} else {
handshakeData.session = session;
if (session._userId) {
accept(null, true);
} else {
accept(‘No login’);
}
}
})
} else {
accept(‘No session’);
}
})

  io.sockets.on('connection', function (socket) {
	  console.log(socket.handshake.session)
	  Controllers.online(_userId, function(err, user) {
		  if (err) {
			  socket.emit('err', { mesg:err })
		  }else{
			  socket.broacast.emit('online', user);
		  }
	  })
	  socket.on('disconnect', function(){
		  Controllers.offline(_userId, function(err, user) {
			  if (err) {
				  socket.emit('err', { mesg: err });
			  } else {
				  socket.broadcast.emit('offline' , user)
			  }
		  })
	  });
	  socket.on('getRoom', function () {
		  Controllers.getOnlineUsers(function (err, users) {
			  if (err) {
				  socket.emit('err', {mg: err});
			  } else {
				  socket.emit('roomData', {users: users, messages: messages});
			  }
		  })
	  });
	  socket.on('createMessage', function (message) {
		  messages.push(message);
		  io.sockets.emit('messageAdded', message);
	  });
  });


5 回复

根据你提供的代码片段,socket.handshake.sessionundefined 的问题可能与 socket.handshake 对象的初始化有关。在你的代码中,io.set('authorization') 函数用于验证客户端连接请求,并尝试从客户端的 cookie 中获取会话信息。如果会话信息成功获取,则将其添加到 handshakeData 对象中。

然而,io.set('authorization') 是一个异步函数,这意味着它可能还没有完成会话信息的设置工作,而 io.sockets.on('connection') 已经被触发了。因此,在 io.sockets.on('connection') 中访问 socket.handshake.session 可能还无法得到预期的结果。

为了确保会话信息已经正确设置,可以在 accept 回调中进行处理,确保只有在会话信息成功设置后才允许连接建立。以下是修改后的代码:

io.set('authorization', function(handshakeData, accept) {
    handshakeData.cookie = Cookie.parse(handshakeData.headers.cookie);
    var connectSid = handshakeData.cookie['connect.sid'];
    connectSid = cookieParser(connectSid, 'technode');
    
    if (connectSid) {
        sessionStore.get(connectSid, function(error, session) {
            if (error) {
                return accept(error.message, false);
            } else {
                handshakeData.session = session;
                if (session._userId) {
                    // 仅在会话信息成功设置后才允许连接
                    return accept(null, true);
                } else {
                    return accept('No login', false);
                }
            }
        });
    } else {
        return accept('No session', false);
    }
});

io.sockets.on('connection', function(socket) {
    // 确保在异步操作完成后访问 session
    console.log(socket.handshake.session);
    
    Controllers.online(socket.handshake.session._userId, function(err, user) {
        if (err) {
            socket.emit('err', { mesg: err });
        } else {
            socket.broadcast.emit('online', user);
        }
    });

    socket.on('disconnect', function() {
        Controllers.offline(socket.handshake.session._userId, function(err, user) {
            if (err) {
                socket.emit('err', { mesg: err });
            } else {
                socket.broadcast.emit('offline', user);
            }
        });
    });

    socket.on('getRoom', function() {
        Controllers.getOnlineUsers(function(err, users) {
            if (err) {
                socket.emit('err', { mg: err });
            } else {
                socket.emit('roomData', { users: users, messages: messages });
            }
        });
    });

    socket.on('createMessage', function(message) {
        messages.push(message);
        io.sockets.emit('messageAdded', message);
    });
});

通过这种方式,你可以确保在 socket.handshake.session 被正确设置之后再访问它,从而避免出现 undefined 的情况。


授权函数里面的session是有值的…

socket.handshake.session._userId

能取到这个值吗?

可以用 passport.socketio 这个库

根据你的描述,socket.handshake.sessionundefined 的原因可能是因为在 io.set('authorization') 中设置 handshakeData.session 的操作没有正确完成。具体来说,sessionStore.get 是一个异步操作,而 accept 函数在 sessionStore.get 回调之前被调用,导致 handshakeData.session 没有被设置。

以下是修正后的代码示例:

io.set('authorization', function(handshakeData, accept) {
    handshakeData.cookie = Cookie.parse(handshakeData.headers.cookie);
    var connectSid = handshakeData.cookie['connect.sid'];

    // 假设这里有一个解析 connect.sid 的函数
    connectSid = cookieParser(connectSid, 'technode');

    if (connectSid) {
        sessionStore.get(connectSid, function(error, session) {
            if (error) {
                return accept(error.message, false);
            }

            handshakeData.session = session;
            if (session._userId) {
                accept(null, true);
            } else {
                accept('No login');
            }
        });
    } else {
        accept('No session');
    }
});

io.sockets.on('connection', function(socket) {
    console.log(socket.handshake.session); // 现在应该可以访问到 session 了

    Controllers.online(socket.handshake.session._userId, function(err, user) {
        if (err) {
            socket.emit('err', { mesg: err });
        } else {
            socket.broadcast.emit('online', user);
        }
    });

    socket.on('disconnect', function() {
        Controllers.offline(socket.handshake.session._userId, function(err, user) {
            if (err) {
                socket.emit('err', { mesg: err });
            } else {
                socket.broadcast.emit('offline', user);
            }
        });
    });

    socket.on('getRoom', function() {
        Controllers.getOnlineUsers(function(err, users) {
            if (err) {
                socket.emit('err', { mg: err });
            } else {
                socket.emit('roomData', { users: users, messages: messages });
            }
        });
    });

    socket.on('createMessage', function(message) {
        messages.push(message);
        io.sockets.emit('messageAdded', message);
    });
});

在这个示例中,sessionStore.get 的回调确保在调用 accept 之前已经设置了 handshakeData.session。这样,在 connection 事件处理程序中,socket.handshake.session 就不会是 undefined 了。

回到顶部