how can I get sessions to work using redis, express & socket.io?

前端 未结 2 1557
温柔的废话
温柔的废话 2020-12-13 22:19

So I am trying to get Sessions to work inside my socket.on(\'connection\', ...) I am trying to get this working using recent versions: Socket.io - 0.9.13, Express - 3.1.0 an

相关标签:
2条回答
  • 2020-12-13 22:46

    Looking at your last note (won't be able to share its state over multiple processes using redis) I had the same problem and found a solution:

    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();
    }
    
    0 讨论(0)
  • 2020-12-13 22:48

    inside the io.configure, you have to link the socket with the http session.

    Here's a piece of code that extracts the cookie (This is using socket.io with xhr-polling, I don't know if this would work for websocket, although I suspect it would work).

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

    Then you can access the session using:

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

    This also has the added benefit that it checks there is a valid session, so only your logged in users can use sockets. You can use a different logic, though.

    0 讨论(0)
提交回复
热议问题