diff --git a/examples/connection-state-recovery-example/README.md b/examples/connection-state-recovery-example/README.md new file mode 100644 index 0000000000..ad3e771611 --- /dev/null +++ b/examples/connection-state-recovery-example/README.md @@ -0,0 +1,25 @@ +# Example with connection state recovery + +This example shows how to use the [Connection state recovery feature](https://socket.io/docs/v4/connection-state-recovery). + +![Video of the example](assets/csr.gif) + +## How to use + +```shell +# choose your module syntax (either ES modules or CommonJS) +$ cd esm/ + +# install the dependencies +$ npm i + +# start the server +$ node index.js +``` + +And point your browser to `http://localhost:3000`. + +You can also run this example directly in your browser on: + +- [CodeSandbox](https://codesandbox.io/p/sandbox/github/socketio/socket.io/tree/main/examples/connection-state-recovery-example/esm?file=index.js) +- [StackBlitz](https://stackblitz.com/github/socketio/socket.io/tree/main/examples/connection-state-recovery-example/esm?file=index.js) diff --git a/examples/connection-state-recovery-example/assets/csr.gif b/examples/connection-state-recovery-example/assets/csr.gif new file mode 100644 index 0000000000..c82f415cbf Binary files /dev/null and b/examples/connection-state-recovery-example/assets/csr.gif differ diff --git a/examples/connection-state-recovery-example/cjs/index.html b/examples/connection-state-recovery-example/cjs/index.html new file mode 100644 index 0000000000..18b3573de5 --- /dev/null +++ b/examples/connection-state-recovery-example/cjs/index.html @@ -0,0 +1,49 @@ + + + + + Connection state recovery | Socket.IO + + +

Status: disconnected

+

Recovered? -

+ +

Latest messages:

+ + + + + + diff --git a/examples/connection-state-recovery-example/cjs/index.js b/examples/connection-state-recovery-example/cjs/index.js new file mode 100644 index 0000000000..d4e4518cac --- /dev/null +++ b/examples/connection-state-recovery-example/cjs/index.js @@ -0,0 +1,53 @@ +const { readFile } = require("node:fs/promises"); +const { createServer } = require("node:http"); +const { Server } = require("socket.io"); + +const httpServer = createServer(async (req, res) => { + if (req.url !== "/") { + res.writeHead(404); + res.end("Not found"); + return; + } + // reload the file every time + const content = await readFile("index.html"); + const length = Buffer.byteLength(content); + + res.writeHead(200, { + "Content-Type": "text/html", + "Content-Length": length, + }); + res.end(content); +}); + +const io = new Server(httpServer, { + connectionStateRecovery: { + // the backup duration of the sessions and the packets + maxDisconnectionDuration: 2 * 60 * 1000, + // whether to skip middlewares upon successful recovery + skipMiddlewares: true, + }, +}); + +io.on("connection", (socket) => { + console.log(`connect ${socket.id}`); + + if (socket.recovered) { + console.log("recovered!"); + console.log("socket.rooms:", socket.rooms); + console.log("socket.data:", socket.data); + } else { + console.log("new connection"); + socket.join("sample room"); + socket.data.foo = "bar"; + } + + socket.on("disconnect", (reason) => { + console.log(`disconnect ${socket.id} due to ${reason}`); + }); +}); + +setInterval(() => { + io.emit("ping", new Date().toISOString()); +}, 1000); + +httpServer.listen(3000); diff --git a/examples/connection-state-recovery-example/cjs/package.json b/examples/connection-state-recovery-example/cjs/package.json new file mode 100644 index 0000000000..359a6a033f --- /dev/null +++ b/examples/connection-state-recovery-example/cjs/package.json @@ -0,0 +1,13 @@ +{ + "name": "connection-state-recovery-example", + "version": "0.0.1", + "private": true, + "type": "commonjs", + "description": "Example with connection state recovery", + "scripts": { + "start": "node index.js" + }, + "dependencies": { + "socket.io": "^4.7.2" + } +} diff --git a/examples/connection-state-recovery-example/esm/index.html b/examples/connection-state-recovery-example/esm/index.html new file mode 100644 index 0000000000..18b3573de5 --- /dev/null +++ b/examples/connection-state-recovery-example/esm/index.html @@ -0,0 +1,49 @@ + + + + + Connection state recovery | Socket.IO + + +

Status: disconnected

+

Recovered? -

+ +

Latest messages:

+ + + + + + diff --git a/examples/connection-state-recovery-example/esm/index.js b/examples/connection-state-recovery-example/esm/index.js new file mode 100644 index 0000000000..96d054a973 --- /dev/null +++ b/examples/connection-state-recovery-example/esm/index.js @@ -0,0 +1,53 @@ +import { readFile } from "node:fs/promises"; +import { createServer } from "node:http"; +import { Server } from "socket.io"; + +const httpServer = createServer(async (req, res) => { + if (req.url !== "/") { + res.writeHead(404); + res.end("Not found"); + return; + } + // reload the file every time + const content = await readFile("index.html"); + const length = Buffer.byteLength(content); + + res.writeHead(200, { + "Content-Type": "text/html", + "Content-Length": length, + }); + res.end(content); +}); + +const io = new Server(httpServer, { + connectionStateRecovery: { + // the backup duration of the sessions and the packets + maxDisconnectionDuration: 2 * 60 * 1000, + // whether to skip middlewares upon successful recovery + skipMiddlewares: true, + }, +}); + +io.on("connection", (socket) => { + console.log(`connect ${socket.id}`); + + if (socket.recovered) { + console.log("recovered!"); + console.log("socket.rooms:", socket.rooms); + console.log("socket.data:", socket.data); + } else { + console.log("new connection"); + socket.join("sample room"); + socket.data.foo = "bar"; + } + + socket.on("disconnect", (reason) => { + console.log(`disconnect ${socket.id} due to ${reason}`); + }); +}); + +setInterval(() => { + io.emit("ping", new Date().toISOString()); +}, 1000); + +httpServer.listen(3000); diff --git a/examples/connection-state-recovery-example/esm/package.json b/examples/connection-state-recovery-example/esm/package.json new file mode 100644 index 0000000000..11b42eec8e --- /dev/null +++ b/examples/connection-state-recovery-example/esm/package.json @@ -0,0 +1,13 @@ +{ + "name": "connection-state-recovery-example", + "version": "0.0.1", + "private": true, + "type": "module", + "description": "Example with connection state recovery", + "scripts": { + "start": "node index.js" + }, + "dependencies": { + "socket.io": "^4.7.2" + } +}