我怎样才能得到会话使用Redis的,表达和socket.io工作?(how can I get se

2019-07-20 19:35发布

所以我试图让会议我socket.on内工作(“连接”,...)我试图让这个工作使用最新版本:Socket.io - 0.9.13,快速 - 3.1.0和最新版本的其他模块。

无论如何,我都用这两个模块的尝试连接,Redis的 '和“ session.socket.io ”,他们都有类似的问题。

在我的代码有2个Redis的商店(socketio.RedisStore和require(“连接-Redis的”)(快递)),现在这个计划都运行良好,但因为表达和socket.io需要共享会话数据,我在想,如果这种设置会正确使用会话? 做会话商店需要对快递/ socketio相同的对象? 一个灰色地带,以我的位,因为2米RedisStore的将使用在后台同一分贝?

我已经使用无论是socket.io redisStore或审判中的连接redis的redisStore在这两个地方,但socket.io犯规喜欢的Connect-redis的redisStore和表达犯规像socketio.redisStore。

如果我使用connect-redis的RedisStore然后socket.io/lib/manager.js抱怨:this.store.subscribe(...的TypeError对象#有没有方法“订阅”

如果我使用socketio.RedisStore然后快递/ node_modules /连接/ lib中/中间件/ session.js抱怨:类型错误:对象#有没有方法“得到”

*注意:我宁愿得到session.socket.io插件的工作,但是当我做相同的设置与该插件,表达(也)抱怨:类型错误:对象#有没有方法“得到”

因此,它是好的,我用2个不同的RedisStores的会话,或者我需要以某种方式得到一个或其他工作两种,如果是这样的任何想法如何解决?

我当前的代码如下所示:

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...');

Answer 1:

里面io.configure ,你必须插座与HTTP会话链接。

这里是一块提取cookie的代码(这是使用socket.io与xhr-polling ,我不,知道这是否会为WebSocket的工作,但我怀疑这会工作)。

var cookie = require('cookie');
var connect = require('connect');

var sessionStore = new RedisStore({
  client: redis // the redis client
});

socketio.set('authorization', function(data, cb) {
  if (data.headers.cookie) {
    var sessionCookie = cookie.parse(data.headers.cookie);
    var sessionID = connect.utils.parseSignedCookie(sessionCookie['connect.sid'], secret);
    sessionStore.get(sessionID, function(err, session) {
      if (err || !session) {
        cb('Error', false);
      } else {
        data.session = session;
        data.sessionID = sessionID;
        cb(null, true);
      }
    });
  } else {
    cb('No cookie', false);
  }
});

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

socket.on("selector", function(data, reply) {
  var session = this.handshake.session;
  ...
}

这也有额外的好处,它会检查有一个有效的会话中,用户可以使用插座所以只有你的记录。 您可以使用不同的逻辑,虽然。



Answer 2:

看你的最后一个音符(将无法通过使用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();
}


文章来源: how can I get sessions to work using redis, express & socket.io?