套接字IO只会话不会持久
我正在使用我正在构build的聊天应用程序中的Socket.io
。 我正在尝试设置会话,以便在会话之间持续login用户。
以下是相关的代码:
index.js (服务器)
var cookieParser = require('cookie-parser')(); var session = require('cookie-session')({ secret: 'secret' }); app.use(cookieParser); app.use(session); io.use(function(socket, next) { var req = socket.handshake; var res = {}; cookieParser(req, res, function(err) { if (err) return next(err); session(req, res, next); }); }); io.on('connection', function(socket){ socket.on('test 1', function(){ socket.handshake.test = 'banana'; }); socket.on('test 2', function(){ console.log(socket.handshake.test); }); });
chat.js (客户端)
var socket = io(); socket.emit('test 1'); socket.emit('test 2');
上面的代码工作,它会打印banana
到预期的控制台。 但是,如果我把“testing1”这样评论出来:
var socket = io(); // socket.emit('test 1'); socket.emit('test 2');
它将打印到控制台undefined
。
它不应该仍然能够打印banana
,因为它正在使用一个会议,并坚持要求之间? 如果我把我称之为“testing1”和“testing2”的顺序颠倒过来,我也碰到同样的问题。
我究竟做错了什么? 我错过了什么会议坚持如预期?
问题是你正在使用cookie-session
,并且socket.io不允许你设置XMLHttpRequest
规范的cookie,也没有在web套接字事务中间的request/response
,所以你不能设置响应cookie。
用你的中间件,你可以看到cookies,但是你不能在socket.io中设置它。 这个例子可以保证:
io.use(function(socket, next) { var req = socket.request; var res = req.res; cookieParser(req, res, function(err) { if (err) return next(err); session(req, res, next); }); }); io.on('connection', function(socket){ var req = socket.request; console.log(req.session.test) socket.on('test 1', function(){ req.session.test = 'banana'; }); socket.on('test 2', function(){ console.log(req.session.test); }); }); app.get('/', function(req, res) { console.log(req.session.test) if (!req.session.test) { req.session.test = 'banana request' } })
你可以使用类似redis
东西来坚持会话,或者在握手中设置一些“黑客”。
另一种select是不使用会话,只需在socket
对象或其他JavaScript对象中设置属性,但在这种情况下,您不能在服务器/服务之间共享对象。
- 如何与Socket.IO 1.x和Express 4.x共享会话?
- https://www.npmjs.com/package/express-socket.io-session
- https://github.com/rakeshok/socket.io-client-cookie
- http://www.w3.org/TR/XMLHttpRequest/
- https://github.com/socketio/socket.io/blob/master/examples/chat/index.js#L35-L36
- 如何将属性关联到Redis Store中的socket.io对象?
- 仍然可以访问标题。
- 您可以在每个套接字的服务器端保存数据:socket.my_value =“任何数据types”;
- 您可以将数据保存在io.sockets对象中,io.my_value =“任何数据types”
所以,例如:
io.on('connection', function(socket){ var id = socket.handshake.query.id; //you can set this in client connection string http://localhost?id=user_id //Validate user, registered etc. and if ok/ if(validateUser(id)) { //if this is reconnect if(io.sessions[id]) { socket.session_id = io.sessions[id].session_id; } else { var session_id = random_value; socket.session_id = some_random_value; io.sessions[id] = { user_id: id, session_id: socket.session_id }; } registerEvent(socket); } else { socket.emit('auth_error', 'wrong user'); } }); function registerEvent(socket) { socket.on('some_event', function(data, callback) { if(!socket.session_id) { callback('unathorized');//or emit socket.emit('auth_error', 'unauthorized'); } //do what you want, user is clear }); }