Cluster adapter
#
How it worksThe Cluster adapter allows to use Socket.IO within a Node.js cluster.
Every packet that is sent to multiple clients (e.g. io.to("room1").emit()
or socket.broadcast.emit()
) is also sent to other workers via the IPC channel.
The source code of this adapter can be found here.
#
Installationnpm install @socket.io/cluster-adapter
#
Usage#
With Node.js clusterconst cluster = require("cluster");const http = require("http");const { Server } = require("socket.io");const numCPUs = require("os").cpus().length;const { setupMaster, setupWorker } = require("@socket.io/sticky");const { createAdapter, setupPrimary } = require("@socket.io/cluster-adapter");
if (cluster.isMaster) { console.log(`Master ${process.pid} is running`);
const httpServer = http.createServer();
// setup sticky sessions setupMaster(httpServer, { loadBalancingMethod: "least-connection", });
// setup connections between the workers setupPrimary();
// needed for packets containing buffers (you can ignore it if you only send plaintext objects) // Node.js < 16.0.0 cluster.setupMaster({ serialization: "advanced", }); // Node.js > 16.0.0 // cluster.setupPrimary({ // serialization: "advanced", // });
httpServer.listen(3000);
for (let i = 0; i < numCPUs; i++) { cluster.fork(); }
cluster.on("exit", (worker) => { console.log(`Worker ${worker.process.pid} died`); cluster.fork(); });} else { console.log(`Worker ${process.pid} started`);
const httpServer = http.createServer(); const io = new Server(httpServer);
// use the cluster adapter io.adapter(createAdapter());
// setup connection with the primary process setupWorker(io);
io.on("connection", (socket) => { /* ... */ });}
#
With PM2See the associated documentation.
recluster
#
With cluster.js
const cluster = require("cluster");const http = require("http");const { setupMaster } = require("@socket.io/sticky");const { setupPrimary } = require("@socket.io/cluster-adapter");const recluster = require("recluster");const path = require("path");
const httpServer = http.createServer();
// setup sticky sessionssetupMaster(httpServer, { loadBalancingMethod: "least-connection",});
// setup connections between the workerssetupPrimary();
// needed for packets containing buffers (you can ignore it if you only send plaintext objects)// Node.js < 16.0.0cluster.setupMaster({ serialization: "advanced",});// Node.js > 16.0.0// cluster.setupPrimary({// serialization: "advanced",// });
httpServer.listen(3000);
const balancer = recluster(path.join(__dirname, "worker.js"));
balancer.run();
worker.js
const http = require("http");const { Server } = require("socket.io");const { setupWorker } = require("@socket.io/sticky");const { createAdapter } = require("@socket.io/cluster-adapter");
const httpServer = http.createServer();const io = new Server(httpServer);
// use the cluster adapterio.adapter(createAdapter());
// setup connection with the primary processsetupWorker(io);
io.on("connection", (socket) => { /* ... */});
#
OptionsName | Description | Default value |
---|---|---|
requestsTimeout | the timeout for inter-server requests such as fetchSockets() or serverSideEmit() with ack | 5000 |