how can I get sessions to work using redis, express & socket.io?
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.
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();}