带有快速会话的 ReactJS 和 socket.io - 套接字未使用正确的会话并创建了许多其他会话
Posted
技术标签:
【中文标题】带有快速会话的 ReactJS 和 socket.io - 套接字未使用正确的会话并创建了许多其他会话【英文标题】:ReactJS and socket.io with express session - socket not using the right session and creating many others 【发布时间】:2019-03-31 22:55:10 【问题描述】:我已经尝试了很多方法来获取 Node.JS 中 socket.io 连接中的 express session 变量,但总是失败。我注意到,每当我使用会话中间件时,都没有使用正确的会话,而是创建了 3 个其他无用的会话(除非 saveUninitialized:true,如果为 false,则不会保存它,但它仍然使用了错误的会话)。
我试过了:
使用 cookie 解析器。 在文件中存储会话。 express-socket.io-session。 redis 还有一些我已经记不起来的事情了。但这一切都归结为一件事 - 套接字不使用与快速请求 (req.session) 相同的会话,而是创建 3 个其他会话,并在套接字活动时继续创建新会话。
App组件内客户端socket.io的设置:
componentWillMount()
let socket = io("http://localhost:5000");
this.setState(socket);
socket.emit("test"); // This actually returns the correct session.
我在 ReactJS 中发送 AJAX 的方式示例:
fetch('http://localhost:5000/home/userinfo',
method: 'GET',
credentials: 'include',
headers:
'Accept': 'application/json',
'Content-Type': 'application/json',
,
).then(function(response)
return response.json();
).then(function(data)
if (data.login)
self.setState(username: data.login);
else
self.props.history.push("/login");
);
快速会话设置:
var sessionMiddleware = session(
store: new sessionFileStore( path: './sessions' ),
secret: 'nothingspecial',
maxAge: new Date(Date.now() + 3600000),
resave: true,
saveUninitialized: false
);
app.use(sessionMiddleware);
socket.io 连接:
const server = app.listen(port, () => console.log(`Listening on port $port`));
const io = require('socket.io').listen(server);
io.use(function(socket, next)
sessionMiddleware(socket.handshake, , next);
);
io.on('connection', function(socket)
console.log('a user connected');
socket.on('disconnect', function()
console.log('user disconnected');
);
socket.on('test', function()
console.log(socket.handshake.session);
// Returns different session than when using app.get and then req.session for example
);
);
还有一些其他 app.use 可能值得在这里发布:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded( extended: false ));
app.use(function (req, res, next)
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
);
非常感谢您的帮助,因为我已经浪费了很多时间试图弄清楚这一点。
编辑:我注意到,当我直接从连接开始的位置(应用程序组件)socket.emit 刷新页面时,它实际上抓住了正确的会话。 我尝试在 App 组件中创建一些函数,但是当我将函数传递给不同的组件并运行 props 函数时,它仍然会创建一个新会话。
我如何通过套接字:
<Route path="/home" render=(props) => <Home ...props socket=this.state.socket /> />
【问题讨论】:
【参考方案1】:我决定从 socket.io 切换到标准 WebSocket(ws),这似乎也更适合我的需求。使用 ws 共享会话非常有效,您只需要在设置会话变量后强制刷新页面即可。
这有助于: ExpressJS & Websocket & session sharing
还要记住,再也没有 req.upgradeReq
这样的东西了。 req 像这样在 wss.connection 上传递:
wss.on('connection', function(ws, req)
//req.upgradeReq = req;
);
【讨论】:
以上是关于带有快速会话的 ReactJS 和 socket.io - 套接字未使用正确的会话并创建了许多其他会话的主要内容,如果未能解决你的问题,请参考以下文章
使用快速会话的套接字 IO - socket.request.res 未定义