如何使用redis,express& amp; socket.io? [英] how can I get sessions to work using redis, express & socket.io?

查看:115
本文介绍了如何使用redis,express& amp; socket.io?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我试图让Sessions工作在我的socket.on('连接',...)
我正在尝试使用最新版本的工作:Socket.io - 0.9.13,Express - 3.1.0和最新版本的其他模块。



无论如何我已经尝试使用两个模块的 connect-redis '和' session.socket。 io ',他们都有类似的问题。



在我的代码中,我有2个redis存储(socketio.RedisStore和require('connect-redis') express)),现在这个程序都运行正常,但是因为express和socket.io需要共享会话数据,我想知道这个设置是否会正确使用会话?会话商店需要与express / socketio相同的对象吗?有一点灰色的地方给我,因为2 RedisStore的将在后台使用相同的数据库?



我试过使用socket.io redisStore或连接-redis redisStore在两个地方,但是socket.io不喜欢connect-redis redisStore和express不像socketio.redisStore。



如果我使用连接redis RedisStore然后socket.io/lib/manager.js抱怨:
this.store.subscribe(...
TypeError对象#没有方法'subscribe'



如果我使用socketio.RedisStore然后express / node_modules / connect / lib / middleware / session.js抱怨:
TypeError:Object#没有方法'get'



(p)*注意,我宁愿让session.socket.io插件工作,但是当我做同样的设置与该插件,express(也)抱怨:
TypeError:Object#没有方法'get'



所以我可以使用两个不同的RedisStores进行会话,或者我需要以某种方式获得一个或另一个工作g,如果有的话,如何解决?



我目前的代码如下:

  var 
CONST = {
port:80,
sessionKey:'你的秘密酱'
};

var
redis = require('redis');

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

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,虽然我怀疑它可以工作)。

  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('无cookie',false);
}
});

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

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

这还有一个额外的好处,它检查有一个有效的会话,所以只有你的登录用户可以使用套接字,但是可以使用不同的逻辑。


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 and latest versions of other modules.

Anyway I have tried using both modules 'connect-redis' and 'session.socket.io' and they both have similar problems.

In my code I have 2 redis stores (socketio.RedisStore and require('connect-redis')(express)), now this program all runs fine, but because express and socket.io need to share session data, I was wondering if this setup will use sessions correctly? do the session stores need to be the same object for express/socketio? A bit of a gray area to me, because the 2 RedisStore's will use the same db in the background?

I have tried using either the socket.io redisStore or the connect-redis redisStore in both places, but socket.io doesnt like the connect-redis redisStore and express doesnt like the socketio.redisStore.

If I use the connect-redis RedisStore then socket.io/lib/manager.js complains: this.store.subscribe(... TypeError Object # has no method 'subscribe'

If I use socketio.RedisStore then express/node_modules/connect/lib/middleware/session.js complains: TypeError: Object # has no method 'get'

*Note I would rather get the session.socket.io plugin working, but when I do the same setup with that plugin, express (also) complains: TypeError: Object # has no method 'get'

So is it ok that I use 2 different RedisStores for sessions, or do I need to somehow get one or the other working for both, and if so any ideas on how to fix?

My current code looks like this:

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

解决方案

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.

这篇关于如何使用redis,express& amp; socket.io?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆