io.controller和io.middleware的context都无法获取到session #1416
Comments
socket.io 和 http 不是一个模型来着 |
那我需要怎么做才可以拿到session呢? |
请提供复现代码 |
module.exports = app => {
return function* (next) {
// this.socket.emit('res', 'connected!');
console.log(this.socket.handshake);
console.log(app.context.sessionOptions);
console.log(this.session.temp);
console.log('connected!');
yield* next;
console.log('disconnection!');
};
}; 基本什么都还没开始处理,就是想先通过web api授权,并拿到session id,然后在socket.io这边可以直接使用session的内容 |
这样看不出什么来。请按照模板提供 Mini Showcase Repository: |
这样,我就想确认,在socke.io的plugin里面,对应的this对象,是不是能拿到session,如果不能,我就自己想办法包装一个,我想这个不需要我提供代码吧? |
@atian25 也就是说如果session是基础cookie的,那么在controller和middleware 中是无法改变session的是吧。 |
@liujinyang1994 可以获取的看下我上面发的例子 |
@ngot 当session使用redis来实现的时候,是取不到的 |
@liujinyang1994 我也发现了这个问题,的确拿不到,但是可以手动从cookie中取一下。 const session = await app.redis.get(this.cookies.get('EGG_SESS', { encrypt: true }));
console.log(JSON.parse(session)); |
@Evilcome 我们要不要再开个issue,他们好像没注意到这个问题。 |
写一个复现的repo,给我调试下 |
@ngot 我写了一个,尝试注释开 https://github.com/Evilcome/egg-socket-redis-session-demo 测试步骤:
我在这里做了更多说明 'use strict';
module.exports = app => {
return function* (next) {
// NOTE: 如果用了 session-redis, 这里就拿不到 session 了,
// 如果尝试把 plugin 中 sessionRedis 注释掉,既可以访问到。
// ISSUES: https://github.com/eggjs/egg/issues/1416
if (!this.session.user) {
return this.socket.emit('forbidden');
}
yield* next;
};
}; |
@Evilcome 赞,我还想晚上写一个来着。 |
查到原因了: 被 socket.io 接管的请求,都不会进去到 同时,https://github.com/koajs/session/blob/master/index.js#L38 koa-session 是在中间件内部,来处理 session-store 逻辑的。 |
cc @fengmk2 |
感觉要重新设计,不同入口进来,创建 ctx,走相同的流程。只是 ctx 会有差异。 |
一个走的是http 一个走的是socketio 两者挂载的父级对象是分开的 完全是两个分支 所以你拿不到 |
这种就属于hack方法了,还是等官方把这个问题修复吧。 |
@killagu 这个跟你思考的也有点像 |
简单的思路不同的协议适配 附上一些伪代码protocolConnection.on('req', req => handleProtocolRequest(req))
// 处理某种协议的请求
function handleProtocolRequest(protocolRequest) {
// 将某种协议的请求封装成req, res对象
// 适应koa的`request`和`response`抽象
const { req, res } = protocolReqImpl(req);
// 创建ctx
const ctx = app.createContext(req, res);
// 处理请求, 使用通用的中间件
app.handleRequest(ctx, app.middleware);
} |
cc @ngot |
两者不应该共享中间件,模型不一样。 socket.io 可以实现一个 session 的中间件,保证两边的通用。其他的还是独立走中间件吧 |
现在有啥简单的workaround么?按照@Evilcome 提到的从cookie拿EGG_SESS,再从redis拿session,这种方法可以拿到session,但是不好存下去。 |
这个问题现在解决了吗? |
这个问题还在解决吗 |
Fix PR: eggjs/egg-socket.io#48 |
|
io.controller和io.middleware都无法获取到session,但app.controller中可以获取,请问是什么原因?
The text was updated successfully, but these errors were encountered: