Skip to content

Commit d744fda

Browse files
docs: improve example with express-session
The example is now available with different syntaxes: - CommonJS - ES modules - TypeScript Related: #4787
1 parent 8259cda commit d744fda

File tree

10 files changed

+308
-2
lines changed

10 files changed

+308
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
const express = require("express");
2+
const { createServer } = require("node:http");
3+
const { join } = require("node:path");
4+
const { Server } = require("socket.io");
5+
const session = require("express-session");
6+
7+
const port = process.env.PORT || 3000;
8+
9+
const app = express();
10+
const httpServer = createServer(app);
11+
12+
const sessionMiddleware = session({
13+
secret: "changeit",
14+
resave: true,
15+
saveUninitialized: true,
16+
});
17+
18+
app.use(sessionMiddleware);
19+
20+
app.get("/", (req, res) => {
21+
res.sendFile(join(__dirname, "index.html"));
22+
});
23+
24+
app.post("/incr", (req, res) => {
25+
const session = req.session;
26+
session.count = (session.count || 0) + 1;
27+
res.status(200).end("" + session.count);
28+
29+
io.to(session.id).emit("current count", session.count);
30+
});
31+
32+
app.post("/logout", (req, res) => {
33+
const sessionId = req.session.id;
34+
req.session.destroy(() => {
35+
// disconnect all Socket.IO connections linked to this session ID
36+
io.to(sessionId).disconnectSockets();
37+
res.status(204).end();
38+
});
39+
});
40+
41+
const io = new Server(httpServer);
42+
43+
io.engine.use(sessionMiddleware);
44+
45+
io.on("connection", (socket) => {
46+
const req = socket.request;
47+
48+
socket.join(req.session.id);
49+
50+
socket.on("incr", (cb) => {
51+
req.session.reload((err) => {
52+
if (err) {
53+
// session has expired
54+
return socket.disconnect();
55+
}
56+
req.session.count = (req.session.count || 0) + 1;
57+
req.session.save(() => {
58+
cb(req.session.count);
59+
});
60+
});
61+
});
62+
});
63+
64+
httpServer.listen(port, () => {
65+
console.log(`application is running at: http://localhost:${port}`);
66+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "express-session-example",
3+
"version": "0.0.1",
4+
"private": true,
5+
"type": "commonjs",
6+
"description": "Example with express-session (https://github.com/expressjs/session)",
7+
"scripts": {
8+
"start": "node index.js"
9+
},
10+
"dependencies": {
11+
"express": "~4.17.3",
12+
"express-session": "~1.17.2",
13+
"socket.io": "^4.7.2"
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Example with express-session</title>
6+
</head>
7+
<body>
8+
<button onclick="incrementWithFetch()">Increment with fetch()</button>
9+
<button onclick="logout()">Logout</button>
10+
<p>Count: <span id="httpCount">0</span></p>
11+
12+
<button onclick="incrementWithEmit()">
13+
Increment with Socket.IO emit()
14+
</button>
15+
<p>Status: <span id="ioStatus">disconnected</span></p>
16+
<p>Count: <span id="ioCount">0</span></p>
17+
18+
<script src="/socket.io/socket.io.js"></script>
19+
<script>
20+
const httpCount = document.getElementById("httpCount");
21+
const ioStatus = document.getElementById("ioStatus");
22+
const ioCount = document.getElementById("ioCount");
23+
24+
const socket = io({
25+
// with WebSocket only
26+
// transports: ["websocket"],
27+
});
28+
29+
async function incrementWithFetch() {
30+
const response = await fetch("/incr", {
31+
method: "post",
32+
});
33+
httpCount.innerText = await response.text();
34+
}
35+
36+
function logout() {
37+
fetch("/logout", {
38+
method: "post",
39+
});
40+
}
41+
42+
async function incrementWithEmit() {
43+
socket.emit("incr", (count) => {
44+
ioCount.innerText = count;
45+
});
46+
}
47+
48+
socket.on("connect", () => {
49+
ioStatus.innerText = "connected";
50+
});
51+
52+
socket.on("disconnect", () => {
53+
ioStatus.innerText = "disconnected";
54+
});
55+
56+
socket.on("current count", (count) => {
57+
ioCount.innerText = count;
58+
});
59+
</script>
60+
</body>
61+
</html>

examples/express-session-example/index.js examples/express-session-example/esm/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import express from "express";
2-
import { createServer } from "http";
2+
import { createServer } from "node:http";
33
import { Server } from "socket.io";
44
import session from "express-session";
55

@@ -17,7 +17,7 @@ const sessionMiddleware = session({
1717
app.use(sessionMiddleware);
1818

1919
app.get("/", (req, res) => {
20-
res.sendFile("./index.html", { root: process.cwd() });
20+
res.sendFile(new URL("./index.html", import.meta.url).pathname);
2121
});
2222

2323
app.post("/incr", (req, res) => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Example with express-session</title>
6+
</head>
7+
<body>
8+
<button onclick="incrementWithFetch()">Increment with fetch()</button>
9+
<button onclick="logout()">Logout</button>
10+
<p>Count: <span id="httpCount">0</span></p>
11+
12+
<button onclick="incrementWithEmit()">
13+
Increment with Socket.IO emit()
14+
</button>
15+
<p>Status: <span id="ioStatus">disconnected</span></p>
16+
<p>Count: <span id="ioCount">0</span></p>
17+
18+
<script src="/socket.io/socket.io.js"></script>
19+
<script>
20+
const httpCount = document.getElementById("httpCount");
21+
const ioStatus = document.getElementById("ioStatus");
22+
const ioCount = document.getElementById("ioCount");
23+
24+
const socket = io({
25+
// with WebSocket only
26+
// transports: ["websocket"],
27+
});
28+
29+
async function incrementWithFetch() {
30+
const response = await fetch("/incr", {
31+
method: "post",
32+
});
33+
httpCount.innerText = await response.text();
34+
}
35+
36+
function logout() {
37+
fetch("/logout", {
38+
method: "post",
39+
});
40+
}
41+
42+
async function incrementWithEmit() {
43+
socket.emit("incr", (count) => {
44+
ioCount.innerText = count;
45+
});
46+
}
47+
48+
socket.on("connect", () => {
49+
ioStatus.innerText = "connected";
50+
});
51+
52+
socket.on("disconnect", () => {
53+
ioStatus.innerText = "disconnected";
54+
});
55+
56+
socket.on("current count", (count) => {
57+
ioCount.innerText = count;
58+
});
59+
</script>
60+
</body>
61+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import express = require("express");
2+
import { createServer } from "http";
3+
import { Server } from "socket.io";
4+
import session from "express-session";
5+
import { type Request } from "express";
6+
7+
declare module "express-session" {
8+
interface SessionData {
9+
count: number;
10+
}
11+
}
12+
13+
const port = process.env.PORT || 3000;
14+
15+
const app = express();
16+
const httpServer = createServer(app);
17+
18+
const sessionMiddleware = session({
19+
secret: "changeit",
20+
resave: true,
21+
saveUninitialized: true,
22+
});
23+
24+
app.use(sessionMiddleware);
25+
26+
app.get("/", (req, res) => {
27+
res.sendFile(new URL("./index.html", import.meta.url).pathname);
28+
});
29+
30+
app.post("/incr", (req, res) => {
31+
const session = req.session;
32+
session.count = (session.count || 0) + 1;
33+
res.status(200).end("" + session.count);
34+
35+
io.to(session.id).emit("current count", session.count);
36+
});
37+
38+
app.post("/logout", (req, res) => {
39+
const sessionId = req.session.id;
40+
req.session.destroy(() => {
41+
// disconnect all Socket.IO connections linked to this session ID
42+
io.to(sessionId).disconnectSockets();
43+
res.status(204).end();
44+
});
45+
});
46+
47+
const io = new Server(httpServer);
48+
49+
io.engine.use(sessionMiddleware);
50+
51+
io.on("connection", (socket) => {
52+
const req = socket.request as Request;
53+
54+
socket.join(req.session.id);
55+
56+
socket.on("incr", (cb) => {
57+
req.session.reload((err) => {
58+
if (err) {
59+
// session has expired
60+
return socket.disconnect();
61+
}
62+
req.session.count = (req.session.count || 0) + 1;
63+
req.session.save(() => {
64+
cb(req.session.count);
65+
});
66+
});
67+
});
68+
});
69+
70+
httpServer.listen(port, () => {
71+
console.log(`application is running at: http://localhost:${port}`);
72+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "express-session-example",
3+
"version": "0.0.1",
4+
"private": true,
5+
"type": "module",
6+
"description": "Example with express-session (https://github.com/expressjs/session)",
7+
"scripts": {
8+
"start": "ts-node index.ts"
9+
},
10+
"dependencies": {
11+
"@types/express": "^4.17.17",
12+
"@types/express-session": "^1.17.7",
13+
"@types/node": "^20.6.0",
14+
"express": "~4.17.3",
15+
"express-session": "~1.17.2",
16+
"socket.io": "^4.7.2",
17+
"ts-node": "^10.9.1",
18+
"typescript": "^5.2.2"
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"compilerOptions": {
3+
"module": "NodeNext",
4+
"moduleResolution": "NodeNext",
5+
"target": "ES2022",
6+
"strict": true
7+
},
8+
"ts-node": {
9+
"esm": true
10+
}
11+
}

0 commit comments

Comments
 (0)