仅套接字 IO 会话不持久
Posted
技术标签:
【中文标题】仅套接字 IO 会话不持久【英文标题】:Socket IO only session not persisting 【发布时间】:2016-04-20 14:14:01 【问题描述】:我在我正在构建的聊天应用程序中使用Socket.io
。我正在尝试设置会话,以便我可以在会话之间保持用户的登录。
以下是相关代码:
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
打印到控制台。但是,如果我像这样注释掉“测试 1”:
var socket = io();
// socket.emit('test 1');
socket.emit('test 2');
它将在控制台打印undefined
。
它是否仍然可以打印banana
,因为它正在使用会话并且在请求之间持续存在?如果我颠倒调用“测试 1”和“测试 2”的顺序,我也会遇到同样的问题。
我做错了什么?为了让会话按预期持续存在,我缺少什么?
【问题讨论】:
将socket.handshake.session.test = 'banana';
用于test 1
和socket.handshake.session.test
用于test 2
是否有效?
【参考方案1】:
问题是您使用的是cookie-session
,并且socket.io 不允许您设置cookie 由于XMLHttpRequest
的规范,而且您在Web 套接字中间没有request/response
交易,所以你不能设置响应cookie。
使用您的中间件,您可以看到 cookie,但您不能在 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
之类的东西来保持会话,或者使用一些“hack”来在握手中设置它。
另一种选择是根本不使用会话,只需在socket
对象或另一个 javascript 对象中设置属性,但在这种情况下,您无法在服务器/服务之间共享该对象。
【讨论】:
【参考方案2】:-
仍然可以访问标题。
您可以在服务器端为每个套接字保存数据:socket.my_value = "any data type";
您可以将数据保存在 io.sockets 对象中,io.my_value = "any data type"
所以,例如:
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
);
【讨论】:
以上是关于仅套接字 IO 会话不持久的主要内容,如果未能解决你的问题,请参考以下文章
带有 socket.io 状态的 UseEffect 钩子在套接字处理程序中不持久
带有快速会话的 ReactJS 和 socket.io - 套接字未使用正确的会话并创建了许多其他会话
使用快速会话的套接字 IO - socket.request.res 未定义
如何将用户名从php会话存储到nodejs中的socket.io库和页面刷新时套接字连接断开。为啥?