Session 如何使用redis、express和;socket.io?

Session 如何使用redis、express和;socket.io?,session,express,redis,socket.io,node-redis,Session,Express,Redis,Socket.io,Node Redis,所以我试图让会话在我的套接字中工作 我正在尝试使用最新版本:Socket.io-0.9.13、Express-3.1.0和其他模块的最新版本来实现这一点 无论如何,我已经尝试使用模块“”和“”,它们都有类似的问题 在我的代码中,我有两个redis存储(socketio.redistore和require('connect-redis')(express)),现在这个程序运行正常,但是由于express和socket.io需要共享会话数据,我想知道这个设置是否能正确使用会话?对于express/s

所以我试图让会话在我的套接字中工作 我正在尝试使用最新版本:Socket.io-0.9.13、Express-3.1.0和其他模块的最新版本来实现这一点

无论如何,我已经尝试使用模块“”和“”,它们都有类似的问题

在我的代码中,我有两个redis存储(socketio.redistore和require('connect-redis')(express)),现在这个程序运行正常,但是由于express和socket.io需要共享会话数据,我想知道这个设置是否能正确使用会话?对于express/socketio,会话存储是否需要是相同的对象?对我来说有点灰色,因为2个Redistore在背景中使用相同的db

我在这两个地方都尝试过使用socket.io Redistore或connect redis Redistore,但是socket.io不喜欢connect redis Redistore,express不喜欢socketio.redistore

如果我使用connect redis Redistore,那么socket.io/lib/manager.js会抱怨: this.store.subscribe(。。。 TypeError对象#没有方法“订阅”

如果我使用socketio.redistore,那么express/node_modules/connect/lib/middleware/session.js会抱怨: TypeError:对象#没有方法“get”

*注意:我宁愿让session.socket.io插件工作,但当我对该插件进行相同的设置时,express(也)抱怨: TypeError:对象#没有方法“get”

那么,我是否可以使用两个不同的RedisStore进行会话,或者我是否需要以某种方式使其中一个或另一个同时工作,如果是这样的话,还有关于如何修复的想法

我当前的代码如下所示:

var
    CONST = {
        port: 80,
        sessionKey: 'your secret sauce'
    };

var 
    redis = require('redis');

var 
    express = require('express'),
    socketio = require('socket.io'),
    RedisStore = require('connect-redis')(express);

var 
    redisStore = new RedisStore(),
    socketStore = new socketio.RedisStore();

var 
    app = express(),
    server = require('http').createServer(app),
    io = socketio.listen(server);

app.configure(function(){
    app.use(express.cookieParser( CONST.sessionKey ));
    app.use(express.session({ secret: CONST.sessionKey, store: redisStore }));
    app.use(express.static(__dirname + '/test'));
    app.get('/', function (req, res) {res.sendfile(__dirname + '/test/' + 'index.htm');});
});

io.configure(function(){
    io.set('log level', 1);
    io.enable('browser client minification');
    io.enable('browser client etag');
    io.enable('browser client gzip');
    io.set('store', socketStore);
});

io.sockets.on('connection', function(socket){
    socket.emit('message', 'Test 1 from server')
});

server.listen( CONST.port );

console.log('running...');

io.configure
中,必须将套接字链接到http会话

下面是一段提取cookie的代码(这是使用socket.io和
xhr polling
,我不知道这是否适用于websocket,尽管我怀疑它会起作用)

然后,您可以使用以下方式访问会话:

socket.on("selector", function(data, reply) {
  var session = this.handshake.session;
  ...
}
这还有一个额外的好处,即它检查是否存在有效的会话,因此只有您登录的用户才能使用套接字。不过,您可以使用不同的逻辑。

查看您最后的注释(无法使用redis在多个进程上共享其状态),我遇到了相同的问题,并找到了解决方案:

var express = require("express.io");
var swig = require('swig');
var redis = require('redis');
var RedisStore = require('connect-redis')(express);

workers = function() {
    var app = express().http().io();

    app.use(express.cookieParser());
    app.use(express.session({
        secret: 'very cool secretcode',
        store: new RedisStore({ client: redis.createClient() })
    }));

    app.io.set('store', new express.io.RedisStore({
        redisPub: redis.createClient(),
        redisSub: redis.createClient(),
        redisClient: redis.createClient()
    }));


    app.get('/', function(req, res) {
        res.render('index');
    });

    app.listen(3000);


    app.io.route('ready', function(req){
        //setup session stuff, use session stuff, etc.  Or make new routes
    });
};

cluster = require('cluster');
numCPUs = require('os').cpus().length;

if (cluster.isMaster)
{
    for (var i = 0; i < numCPUs; i++)
    {
        cluster.fork();
    }
}
else
{
    workers();
}
var express=require(“express.io”);
var swig=需要(“swig”);
var redis=需要('redis');
var redistore=require('connect-redis')(express);
工人=职能(){
var app=express().http().io();
use(express.cookieParser());
应用程序使用(express.session)({
秘密:“非常酷的秘密代码”,
存储区:新的RedisStore({client:redis.createClient()})
}));
app.io.set('store',new express.io.redistore({
redisPub:redis.createClient(),
redisSub:redis.createClient(),
redisClient:redis.createClient()
}));
app.get('/',函数(req,res){
res.render(“索引”);
});
app.listen(3000);
app.io.route('ready',功能(req){
//设置会话内容、使用会话内容等或创建新路由
});
};
集群=需要(“集群”);
numpus=require('os').cpus().length;
if(cluster.isMaster)
{
对于(变量i=0;i
感谢您的快速回复,如果我想使用session.socket.io插件,那么这是相同的解决方案吗?或者这是一个不同的问题吗?这不使用session.socket.io插件,适用于最新版本的socket.io和express。看起来很有效,我们希望使用session.socket.io,但效果很好,谢谢。注意:要使其正常工作,我必须删除'io.set('store',socketStore);'这确实是一个非常不幸的妥协,因为这意味着socket.io将无法使用redis在多个进程上共享其状态:(希望我将来能找到一种方法。这里的关键是
app.io.set('store',new express.io.redistore({
使用express.io.redistore。谢谢!
var express = require("express.io");
var swig = require('swig');
var redis = require('redis');
var RedisStore = require('connect-redis')(express);

workers = function() {
    var app = express().http().io();

    app.use(express.cookieParser());
    app.use(express.session({
        secret: 'very cool secretcode',
        store: new RedisStore({ client: redis.createClient() })
    }));

    app.io.set('store', new express.io.RedisStore({
        redisPub: redis.createClient(),
        redisSub: redis.createClient(),
        redisClient: redis.createClient()
    }));


    app.get('/', function(req, res) {
        res.render('index');
    });

    app.listen(3000);


    app.io.route('ready', function(req){
        //setup session stuff, use session stuff, etc.  Or make new routes
    });
};

cluster = require('cluster');
numCPUs = require('os').cpus().length;

if (cluster.isMaster)
{
    for (var i = 0; i < numCPUs; i++)
    {
        cluster.fork();
    }
}
else
{
    workers();
}