복붙노트

[REDIS] 어떻게 레디 스를 사용하여 작업에 세션을 얻을 수 있습니다, 표현 및 socket.io?

REDIS

어떻게 레디 스를 사용하여 작업에 세션을 얻을 수 있습니다, 표현 및 socket.io?

내 socket.on 내부 작업에 세션을 얻기 위해 노력하고 있어요 그래서 ( '연결', ...) - 0.9.13, 고속 - 3.1.0 및 다른 모듈의 최신 버전 Socket.io :이 작업을 사용하여 최신 버전을 얻기 위해 노력하고 있어요.

어쨌든 나는 두 모듈의 연결 - 레디 스 '와'session.socket.io '를 사용하여 시도하고 그들은 모두 비슷한 문제가있다.

내 코드에서 나는 2 개 레디 스 상점이 (socketio.RedisStore를하고 ( '연결 - 레디 스') (표현) 필요) 명시 공유 세션 데이터에 socket.io 필요, 나는 궁금했다, 지금은이 프로그램의 모든 실행 잘 때문이 아니라 이 설정이 제대로 세션을 사용할 것인가? 세션 저장 특급 / socketio에 대해 동일한 개체를해야합니까? 나에게 회색 영역의 비트, 2 RedisStore 년대 백그라운드에서 같은 DB를 사용하기 때문에?

나는 socket.io redisStore 또는를 사용하여 시도 연결 - 레디 스 redisStore 두 곳에서,하지만 같은 socket.io 나던 redisStore와 socketio.redisStore 같은 표현 나던을-연결 레디 스.

내가 사용하는 경우는 연결 - 레디 스는 socket.io/lib/manager.js 불평 RedisStore : (this.store.subscribe ... 형식 오류 개체 번호가있는 방법 '구독'을이 없습니다

내가 socketio.RedisStore를 사용하는 경우 다음 / node_modules / 연결 / lib 디렉토리 / 미들웨어 / session.js이 불만을 표현 : 형식 오류 : 개체 번호가있는 방법 '수'를이 없습니다

* 차라리 작업 플러그인 session.socket.io을 얻을 것 참고,하지만 난 그 플러그인과 같은 설정을 수행 할 때, 표현 (도) 불평 : 형식 오류 : 개체 번호가있는 방법 '수'를이 없습니다

그래서 내가 해결하는 방법에 어떤 아이디어 그렇다면 세션이 다른 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...');

해결법

  1. ==============================

    1.io.configure 내부에, 당신은 HTTP 세션에 소켓을 연결해야합니다.

    io.configure 내부에, 당신은 HTTP 세션에 소켓을 연결해야합니다.

    여기에 쿠키를 추출 코드의 조각 (이것은 웹 소켓을 위해 일한다면 나는 그것이 작동합니다 생각하지만 이것은 XHR 폴링와 socket.io를 사용하여, 내가 모르는 경우)입니다.

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

    이것은 또한 그렇게 만 소켓을 사용하여 로그인 한 사용자가 유효한 세션이 확인하는 추가 혜택을 가지고 있습니다. 당신은하지만, 다른 논리를 사용할 수 있습니다.

  2. ==============================

    2.마지막 노트를 보면 저도 같은 문제가 있었하고 해결책을 발견 (레디 스를 사용하여 여러 프로세스를 통해 상태를 공유 할 수 없습니다)

    마지막 노트를 보면 저도 같은 문제가 있었하고 해결책을 발견 (레디 스를 사용하여 여러 프로세스를 통해 상태를 공유 할 수 없습니다)

    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();
    }
    
  3. from https://stackoverflow.com/questions/15169418/how-can-i-get-sessions-to-work-using-redis-express-socket-io by cc-by-sa and MIT license