Node.js 为什么插座io';s get无法从持久会话获取数据?

Node.js 为什么插座io';s get无法从持久会话获取数据?,node.js,express,socket.io,Node.js,Express,Socket.io,在这里,我使用套接字io的get,在每个页面上重新加载它都会给我新的值(理想情况下,它应该来自会话,并且应该是相同的)。你能指出原因吗 var express = require('express'); var app = express(); var server = require('http').createServer(app); var io = require('socket.io').listen(server); var _ = require('lodash'); var q

在这里,我使用套接字io的get,在每个页面上重新加载它都会给我新的值(理想情况下,它应该来自会话,并且应该是相同的)。你能指出原因吗

var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
var _ = require('lodash');
var q = require('q');

server.listen(3000);

var userCounter = 0;
    app.use(express.cookieParser());
    app.use(express.cookieSession({secret: 'secret', key: 'express.sid', cookie:{ path: '/', httpOnly: true, maxAge: (1000*3600*24)} }));
    app.use(express.static('public'))
   .use(function (req, res) {
        res.end('File not available\n');
    });

function getUserName(socket) {
    var deferred = q.defer();
    socket.get('userName', function (err, Name) {
        if (err || !Name) { // PROBLEM: It always goes in to this IF
            var userName = "Userno: " + (userCounter + 1);
            userCounter++;
            socket.set('userName', userName, function () {
                deferred.resolve(userName);
            });
        } else {
            deferred.resolve(Name);
        }
    });
    return deferred.promise;
}

io.sockets.on('connection', function (socket) {
    getUserName(socket).
        then(function (userName) {
            socket.emit("welcome", userName);
            _(io.sockets.sockets).forEach(function (eSocket) {
                if (socket !== eSocket)
                    eSocket.emit("userAdded", userName);
            });
            socket.on('disconnect', function () {
                socket.get('userName', function (err, userName) {
                    io.sockets.emit('userRem', userName);
                });
            });
        });

});

您尚未对您的
socket.io
实施任何会话身份验证。默认情况下,
socket.io
的每个连接都是一个新连接,尽管它具有相同的cookie(cookie中的会话id)。有一个for
socket.io
,用于通过身份验证功能传递每个请求,例如:

var sAuthorization = function(req, cb) {
    if ( req.headers.cookie ) { 
        cb(null, true); return; // We have cookie
    } else {
        cb(null, false); return; // We don't have cookie drop the connection
    };

var socket = require('socket.io').listen(app, { authorization: sAuthorization });
    
您应该做些什么才能使其正常工作(我不会将其作为代码编写,因为需要进行大量修改):

  • 在express中的初始
    http
    连接中为用户指定一个名称(应为每个用户的唯一会话指定一个用户名)
  • 实现可通过express&socket.io访问的sessionStore(有关如何实现的一些想法,请参阅(它使用
    nowjs
    ,但您必须查看sessionStore代码)。实际上,最好将sessionStore放在某个数据库中,而不是内存中
  • 使您的
    socket.io
    authorization sub访问此会话存储并获取用户名,然后像往常一样将其作为此套接字的参数:
    socket.set('name',…
  • 差不多就是这样。虽然没有听起来那么难,但这是正确的方法

    进一步阅读:

  • 更新: 看看这个答案,它会对你很有帮助

    更新二: 我在这里创建了一个Gist文件,其中包含该代码

    var express=require('express'),
    app=express(),
    http=require('http'),
    服务器=http.createServer(应用程序),
    用户=0,
    MemoryStore=express.session.MemoryStore,
    sessionStore=新的MemoryStore(),
    parseCookie=require('cookie')。parse,
    utils=require('connect')。utils,
    io=require('socket.io')。侦听(服务器);
    app.use(express.bodyParser());
    app.use(express.cookieParser('secret');
    使用(express.session({secret:'secret',store:sessionStore}));
    app.get('/',函数(req,res){
    var user=req.session.username?req.session.username:null;
    如果(!用户){
    用户='user_'+用户++;
    req.session.username=用户;
    session.save();
    }
    res.send('\
    \
    \
    \
    欢迎“+用户+”\
    \
    \
    var socket=io.connect()\
    发出(“消息”,“你好”)\
    \
    \
    ');
    });
    io.configure(函数(){
    io.set('授权',函数(请求,回调){
    var cookie=parseCookie(request.headers.cookie);
    如果(!cookie&&!cookie['connect.sid']){
    返回回调(null,false);
    }否则{
    sessionStore.get(utils.parseSignedCookie(cookie['connect.sid'],'secret'),函数(err,session){
    如果(错误){
    回调(err.message,false);
    }否则{
    if(session&&session.username){
    request.user=session.username;
    回调(null,true);
    }否则{
    回调(null,false);
    }
    }
    });
    }
    });
    });
    io.sockets.on('connection',函数(socket){
    socket.on('message',函数(msg){
    console.log(msg+'from'+socket.handshake.user);
    });
    });
    服务器监听(8000);
    
    您尚未对
    套接字.io
    实施任何会话身份验证。默认情况下,到
    套接字.io
    的每个连接都是一个新连接,尽管它具有相同的cookie(cookie中的会话id)。有一个for
    套接字.io
    用于通过身份验证功能传递每个请求,例如:

    var sAuthorization = function(req, cb) {
        if ( req.headers.cookie ) { 
            cb(null, true); return; // We have cookie
        } else {
            cb(null, false); return; // We don't have cookie drop the connection
        };
    
    var socket = require('socket.io').listen(app, { authorization: sAuthorization });
        
    
    您应该做些什么才能使其正常工作(我不会将其作为代码编写,因为需要进行大量修改):

  • 在express中的初始
    http
    连接中为用户指定一个名称(应为每个用户的唯一会话指定一个用户名)
  • 实现可通过express&socket.io访问的sessionStore(有关如何实现的一些想法,请参阅(它使用
    nowjs
    ,但您必须查看sessionStore代码)。实际上,最好将sessionStore放在某个数据库中,而不是内存中
  • 使您的
    socket.io
    authorization sub访问此会话存储并获取用户名,然后像往常一样将其作为此套接字的参数:
    socket.set('name',…
  • 差不多就是这样。虽然没有听起来那么难,但这是正确的方法

    进一步阅读:

  • 更新: 看看这个答案,它会对你很有帮助

    更新二: 我在这里创建了一个Gist文件,其中包含该代码

    var express=require('express'),
    app=express(),
    http=require('http'),
    服务器=http.createServer(应用程序),
    用户=0,
    MemoryStore=express.session.MemoryStore,
    sessionStore=新的MemoryStore(),
    parseCookie=require('cookie')。parse,
    utils=require('connect')。utils,
    io=require('socket.io')。侦听(服务器);
    app.use(express.bodyParser());
    app.use(express.cookieParser('secret');
    使用(express.session({secret:'secret',store:sessionStore}));
    app.get('/',函数(req,res){
    var user=req.session.username?req.session.username:null;
    如果(!用户){
    用户='user_'+用户++;
    req.session.username=用户;
    session.save();
    }
    res.send('\
    \
    \
    \
    欢迎“+用户+”\
    \
    \
    var socket=io.connect()\
    发出(“消息”,“你好”)\
    \
    \