I'm trying to share session data between Express and SocketIO on a nodejs server. I researched online the came across how to implement it at https://socket.io/docs/v3/faq/#Usage-with-express-session
NOTE: FRONT-END AND BACK-END CODE AT BOTTOM
Anytime I visit the homepage at http://localhost:5000 the socket is successfully connected and session contains myData value that is set in socketio initial connection
SocketIO Console Output
Session {
cookie: {
path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true,
secure: true
},
myData: 'hello world'
}
However when a request is sent to http://localhost:5000/api/download the console output in the Express handler does not contain the myData value in the session. This indicates that even though socketIO is saving session data, it is not sharing it with Express.
Express Handler Console Output
Session {
cookie: {
path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true,
secure: true
}
}
I have searched all over the internet and I can't seem to figure it out. The socketIO documentation is not helpful either. I also tried other solutions here on stackoverflow but none seems to work.
- 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?
This question is my last attempt to find help an solve the problem.
Thank You
MY CODE SET UP FOR BOTH FRONT-END AND BACK-END
FRONT-END 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>
FRONT-END: (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";
});
BACK-END:
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}`);
});