如何使用 redis、express & 使会话正常工作socket.io? [英] how can I get sessions to work using redis, express & socket.io?
问题描述
所以我试图让 Sessions 在我的 socket.on('connection', ...)我正在尝试使用最新版本使其正常工作:Socket.io - 0.9.13、Express - 3.1.0 和其他模块的最新版本.
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.
无论如何我已经尝试使用两个模块connect-redis"和session.socket.io' 他们都有类似的问题.
Anyway I have tried using both modules 'connect-redis' and 'session.socket.io' and they both have similar problems.
在我的代码中,我有 2 个 redis 存储(socketio.RedisStore 和 require('connect-redis')(express)),现在这个程序都运行良好,但是因为 express 和 socket.io 需要共享会话数据,我想知道此设置是否会正确使用会话?会话存储是否需要是 express/socketio 的相同对象?对我来说有点灰色地带,因为 2 个 RedisStore 将在后台使用相同的数据库?
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?
我曾尝试在两个地方使用 socket.io redisStore 或 connect-redis redisStore,但 socket.io 不喜欢 connect-redis redisStore,express 不喜欢 socketio.redisStore.
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.
如果我使用 connect-redis RedisStore 然后 socket.io/lib/manager.js 抱怨:this.store.subscribe(...TypeError Object # 没有方法订阅"
If I use the connect-redis RedisStore then socket.io/lib/manager.js complains: this.store.subscribe(... TypeError Object # has no method 'subscribe'
如果我使用 socketio.RedisStore 然后 express/node_modules/connect/lib/middleware/session.js 抱怨:类型错误:对象 # 没有方法get"
If I use socketio.RedisStore then express/node_modules/connect/lib/middleware/session.js complains: TypeError: Object # has no method 'get'
*注意我宁愿让 session.socket.io 插件工作,但是当我用那个插件做同样的设置时,express(也)抱怨:类型错误:对象 # 没有方法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'
那么我可以使用 2 个不同的 RedisStore 进行会话,还是我需要以某种方式让其中一个同时为两者工作,如果是这样,有什么解决方法的想法吗?
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...');
推荐答案
在 io.configure
中,您必须将套接字与 http 会话链接起来.
inside the io.configure
, you have to link the socket with the http session.
这是一段提取cookie的代码(这是使用socket.io和xhr-polling
,我不知道这是否适用于websocket,虽然我怀疑它会起作用).
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 & 使会话正常工作socket.io?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!