Skip to content

Commit ccbb4c0

Browse files
docs: add example with connection state recovery
1 parent d744fda commit ccbb4c0

File tree

8 files changed

+255
-0
lines changed

8 files changed

+255
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Example with connection state recovery
2+
3+
This example shows how to use the [Connection state recovery feature](https://socket.io/docs/v4/connection-state-recovery).
4+
5+
![Video of the example](assets/csr.gif)
6+
7+
## How to use
8+
9+
```shell
10+
# choose your module syntax (either ES modules or CommonJS)
11+
$ cd esm/
12+
13+
# install the dependencies
14+
$ npm i
15+
16+
# start the server
17+
$ node index.js
18+
```
19+
20+
And point your browser to `http://localhost:3000`.
21+
22+
You can also run this example directly in your browser on:
23+
24+
- [CodeSandbox](https://codesandbox.io/p/sandbox/github/socketio/socket.io/tree/main/examples/connection-state-recovery-example/esm?file=index.js)
25+
- [StackBlitz](https://stackblitz.com/github/socketio/socket.io/tree/main/examples/connection-state-recovery-example/esm?file=index.js)
Loading
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Connection state recovery | Socket.IO</title>
6+
</head>
7+
<body>
8+
<p>Status: <span id="connectionStatus">disconnected</span></p>
9+
<p>Recovered? <span id="recoveryStatus">-</span></p>
10+
11+
<p>Latest messages:</p>
12+
<ul id="messages"></ul>
13+
14+
<script src="/socket.io/socket.io.js"></script>
15+
<script>
16+
const $connectionStatus = document.getElementById("connectionStatus");
17+
const $recoveryStatus = document.getElementById("recoveryStatus");
18+
const $messages = document.getElementById("messages");
19+
20+
const socket = io({
21+
reconnectionDelay: 5000 // 1000 by default
22+
});
23+
24+
socket.on("connect", () => {
25+
$connectionStatus.innerText = "connected";
26+
$recoveryStatus.innerText = "" + socket.recovered;
27+
28+
setTimeout(() => {
29+
// close the low-level connection and trigger a reconnection
30+
socket.io.engine.close();
31+
}, Math.random() * 5000 + 1000);
32+
});
33+
34+
socket.on("disconnect", () => {
35+
$connectionStatus.innerText = "disconnected";
36+
$recoveryStatus.innerText = "-"
37+
});
38+
39+
socket.on("ping", (value) => {
40+
const item = document.createElement("li");
41+
item.textContent = value;
42+
$messages.prepend(item);
43+
if ($messages.childElementCount > 10) {
44+
$messages.removeChild($messages.lastChild);
45+
}
46+
});
47+
</script>
48+
</body>
49+
</html>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
const { readFile } = require("node:fs/promises");
2+
const { createServer } = require("node:http");
3+
const { Server } = require("socket.io");
4+
5+
const httpServer = createServer(async (req, res) => {
6+
if (req.url !== "/") {
7+
res.writeHead(404);
8+
res.end("Not found");
9+
return;
10+
}
11+
// reload the file every time
12+
const content = await readFile("index.html");
13+
const length = Buffer.byteLength(content);
14+
15+
res.writeHead(200, {
16+
"Content-Type": "text/html",
17+
"Content-Length": length,
18+
});
19+
res.end(content);
20+
});
21+
22+
const io = new Server(httpServer, {
23+
connectionStateRecovery: {
24+
// the backup duration of the sessions and the packets
25+
maxDisconnectionDuration: 2 * 60 * 1000,
26+
// whether to skip middlewares upon successful recovery
27+
skipMiddlewares: true,
28+
},
29+
});
30+
31+
io.on("connection", (socket) => {
32+
console.log(`connect ${socket.id}`);
33+
34+
if (socket.recovered) {
35+
console.log("recovered!");
36+
console.log("socket.rooms:", socket.rooms);
37+
console.log("socket.data:", socket.data);
38+
} else {
39+
console.log("new connection");
40+
socket.join("sample room");
41+
socket.data.foo = "bar";
42+
}
43+
44+
socket.on("disconnect", (reason) => {
45+
console.log(`disconnect ${socket.id} due to ${reason}`);
46+
});
47+
});
48+
49+
setInterval(() => {
50+
io.emit("ping", new Date().toISOString());
51+
}, 1000);
52+
53+
httpServer.listen(3000);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "connection-state-recovery-example",
3+
"version": "0.0.1",
4+
"private": true,
5+
"type": "commonjs",
6+
"description": "Example with connection state recovery",
7+
"scripts": {
8+
"start": "node index.js"
9+
},
10+
"dependencies": {
11+
"socket.io": "^4.7.2"
12+
}
13+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Connection state recovery | Socket.IO</title>
6+
</head>
7+
<body>
8+
<p>Status: <span id="connectionStatus">disconnected</span></p>
9+
<p>Recovered? <span id="recoveryStatus">-</span></p>
10+
11+
<p>Latest messages:</p>
12+
<ul id="messages"></ul>
13+
14+
<script src="/socket.io/socket.io.js"></script>
15+
<script>
16+
const $connectionStatus = document.getElementById("connectionStatus");
17+
const $recoveryStatus = document.getElementById("recoveryStatus");
18+
const $messages = document.getElementById("messages");
19+
20+
const socket = io({
21+
reconnectionDelay: 5000 // 1000 by default
22+
});
23+
24+
socket.on("connect", () => {
25+
$connectionStatus.innerText = "connected";
26+
$recoveryStatus.innerText = "" + socket.recovered;
27+
28+
setTimeout(() => {
29+
// close the low-level connection and trigger a reconnection
30+
socket.io.engine.close();
31+
}, Math.random() * 5000 + 1000);
32+
});
33+
34+
socket.on("disconnect", () => {
35+
$connectionStatus.innerText = "disconnected";
36+
$recoveryStatus.innerText = "-"
37+
});
38+
39+
socket.on("ping", (value) => {
40+
const item = document.createElement("li");
41+
item.textContent = value;
42+
$messages.prepend(item);
43+
if ($messages.childElementCount > 10) {
44+
$messages.removeChild($messages.lastChild);
45+
}
46+
});
47+
</script>
48+
</body>
49+
</html>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { readFile } from "node:fs/promises";
2+
import { createServer } from "node:http";
3+
import { Server } from "socket.io";
4+
5+
const httpServer = createServer(async (req, res) => {
6+
if (req.url !== "/") {
7+
res.writeHead(404);
8+
res.end("Not found");
9+
return;
10+
}
11+
// reload the file every time
12+
const content = await readFile("index.html");
13+
const length = Buffer.byteLength(content);
14+
15+
res.writeHead(200, {
16+
"Content-Type": "text/html",
17+
"Content-Length": length,
18+
});
19+
res.end(content);
20+
});
21+
22+
const io = new Server(httpServer, {
23+
connectionStateRecovery: {
24+
// the backup duration of the sessions and the packets
25+
maxDisconnectionDuration: 2 * 60 * 1000,
26+
// whether to skip middlewares upon successful recovery
27+
skipMiddlewares: true,
28+
},
29+
});
30+
31+
io.on("connection", (socket) => {
32+
console.log(`connect ${socket.id}`);
33+
34+
if (socket.recovered) {
35+
console.log("recovered!");
36+
console.log("socket.rooms:", socket.rooms);
37+
console.log("socket.data:", socket.data);
38+
} else {
39+
console.log("new connection");
40+
socket.join("sample room");
41+
socket.data.foo = "bar";
42+
}
43+
44+
socket.on("disconnect", (reason) => {
45+
console.log(`disconnect ${socket.id} due to ${reason}`);
46+
});
47+
});
48+
49+
setInterval(() => {
50+
io.emit("ping", new Date().toISOString());
51+
}, 1000);
52+
53+
httpServer.listen(3000);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "connection-state-recovery-example",
3+
"version": "0.0.1",
4+
"private": true,
5+
"type": "module",
6+
"description": "Example with connection state recovery",
7+
"scripts": {
8+
"start": "node index.js"
9+
},
10+
"dependencies": {
11+
"socket.io": "^4.7.2"
12+
}
13+
}

0 commit comments

Comments
 (0)