【发布时间】:2021-04-20 07:13:35
【问题描述】:
我正在尝试在 nodejs 服务器上的 Express 和 SocketIO 之间共享会话数据。我在网上研究了如何在https://socket.io/docs/v3/faq/#Usage-with-express-session实现它
注意:底部的前端和后端代码
每当我访问 http://localhost:5000 的主页时,套接字已成功连接,并且会话包含设置的 myData 值在socketio初始连接中
SocketIO 控制台输出
Session {
cookie: {
path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true,
secure: true
},
myData: 'hello world'
}
但是,当请求发送到 http://localhost:5000/api/download 时,Express 处理程序中的控制台输出不包含 myData 会话中的值。 这表明即使 socketIO 正在保存会话数据,它也不会与 Express 共享。
Express Handler 控制台输出
Session {
cookie: {
path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true,
secure: true
}
}
我在整个互联网上搜索过,但我似乎无法弄清楚。 socketIO 文档也没有帮助。 我还在 stackoverflow 上尝试了其他解决方案,但似乎都没有。
- How to share sessions with Socket.IO 1.x and Express 4.x?
- express-session isn't setting session cookie while using with socket.io
- socket.io and session?
这个问题是我最后一次尝试寻求帮助来解决问题。
谢谢
我的前端和后端代码设置
前端 HTML:(index.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
crossorigin="anonymous"
/>
<title>File Download Progress</title>
</head>
<body class="vh-100 w-2">
<div class="d-flex flex-column align-items-center vh-100">
<div>
<div class="d-flex flex-column align-items-center mt-5">
<h1 class="m-5">File Download Progress</h1>
<button class="m-1 w-100 btn btn-success" id="dl-btn">
Download
</button>
</div>
</div>
</div>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
crossorigin="anonymous"
></script>
<script src="./socket.io.min.js"></script>
<script src="./app.js"></script>
</body>
</html>
前端:(app.js)
const downloadBtn = document.getElementById("dl-btn");
const socket = io("http://localhost:5000");
socket.on("connected", () => {
console.log("server connected");
});
downloadBtn.addEventListener("click", () => {
window.location = "http://localhost:5000/api/download";
});
后端:
import express from "express";
import session from "express-session";
import { createServer } from "http";
import { Server } from "socket.io";
import cors from "cors";
import bodyParser from "body-parser";
import asyncHandler from "express-async-handler";
const app = express();
const server = createServer(app);
const io = new Server(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
},
});
const port = 5000;
const corsOptions = {
origin: "http://localhost:3000",
optionsSuccessStatus: 200,
};
const sessionMiddleware = session({
secret: "keyboard cat",
resave: false,
saveUninitialized: true,
cookie: { secure: true },
});
app.use(cors(corsOptions));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(sessionMiddleware);
io.use((socket, next) => {
sessionMiddleware(socket.request, socket.request.res || {}, next);
});
app.get("/api/", (req, res) => {
res.send("API is running");
});
app.get(
"/api/download",
asyncHandler(async (req, res) => {
console.log(req.session);
res.send("hello");
})
);
io.on("connection", (socket) => {
socket.emit("connected");
console.log("client connected");
const session = socket.request.session;
session.myData = "hello world";
session.save();
console.log(session);
});
server.listen(port, () => {
console.log(`listening at http://localhost:${port}`);
});
【问题讨论】:
-
你看过socket.io/docs/v3/middlewares这里的文档吗,讨论
wrap函数 -
使用提供的链接中“与 Express 中间件的兼容性”部分的示例修改了代码。结果是一样的。如果您启动 node.js 服务器并复制我的代码然后尝试一下,您会发现它不是!工作。
-
您是否看到与此处提供的完整护照示例相同的结果github.com/socketio/socket.io/blob/master/examples/…
-
@TommyBs 我没试过。由于我不打算进行任何身份验证,我认为我不需要 passport.js?
-
当时我无法尝试任何事情,这就是为什么我认为(希望)一个可行的示例可能是一个很好的起点。我会看看我是否可以使用示例
标签: javascript node.js express session socket.io