Socket.IO adapter backed by BoltQ message queue. Scale Socket.IO across multiple servers using BoltQ pub/sub instead of Redis.
BoltQ Server
(Pub/Sub + WAL)
▲ │
publish │ │ subscribe
┌─────┘ └─────┐
│ │
Socket.IO Server 1 Socket.IO Server 2
│ │
┌────┴────┐ ┌────┴────┐
│ Clients │ │ Clients │
└─────────┘ └─────────┘
npm install @boltq/socket.io-adapterimport { Server } from "socket.io";
import { createAdapter } from "@boltq/socket.io-adapter";
const io = new Server(3000);
// Connect to BoltQ server
io.adapter(createAdapter({
host: "127.0.0.1",
port: 9090, // BoltQ HTTP port (WebSocket at /ws)
}));
// That's it! Events are now broadcast across all servers.
io.on("connection", (socket) => {
socket.on("chat", (msg) => {
io.emit("chat", msg); // Delivered to ALL clients on ALL servers
});
});createAdapter({
host: "127.0.0.1", // BoltQ server host
port: 9090, // BoltQ HTTP port
key: "socket.io", // Channel prefix (namespace isolation)
apiKey: "", // BoltQ API key (if auth enabled)
requestsTimeout: 5000, // Inter-server request timeout (ms)
reconnectInterval: 2000, // Reconnect delay on disconnect (ms)
});// server-1.js (port 3001)
import { Server } from "socket.io";
import { createAdapter } from "@boltq/socket.io-adapter";
const io = new Server(3001);
io.adapter(createAdapter({ host: "boltq-host", port: 9090 }));
io.on("connection", (socket) => {
socket.on("message", (data) => {
// This reaches clients on server-2 too
io.to("room1").emit("message", data);
});
});// server-2.js (port 3002)
import { Server } from "socket.io";
import { createAdapter } from "@boltq/socket.io-adapter";
const io = new Server(3002);
io.adapter(createAdapter({ host: "boltq-host", port: 9090 }));
io.on("connection", (socket) => {
socket.join("room1");
});Events emitted to rooms are delivered to all matching clients across all servers.
io.to("room1").emit("event", data); // Room broadcast
io.except("room2").emit("event", data); // Broadcast with exclusion
socket.broadcast.emit("event", data); // All except sender// Fetch all sockets across all servers
const sockets = await io.fetchSockets();
// Get all rooms across all servers
const rooms = await io.adapter.allRooms();
// Make remote sockets join a room
await io.in("room1").socketsJoin("room2");
// Disconnect remote sockets
await io.in("room1").disconnectSockets(true);// Send events between Socket.IO servers (not to clients)
io.serverSideEmit("deploy", { version: "1.2.3" });
io.on("deploy", (data) => {
console.log("Deploy event from another server:", data);
});The adapter automatically reconnects to BoltQ if the connection drops, with configurable retry interval.
- Broadcast: When a server emits an event, it delivers locally AND publishes to BoltQ pub/sub topic
- Receive: All other servers subscribed to the same topic receive the event and deliver to their local clients
- Rooms: Room membership is tracked locally per server. Cross-server room operations use an RPC pattern via BoltQ pub/sub
- RPC: Distributed operations (fetchSockets, allRooms, etc.) use a request/response pattern with timeout
| Channel | Purpose |
|---|---|
socket.io#/# |
Global broadcast for default namespace |
socket.io#/chat# |
Broadcast for /chat namespace |
socket.io-request#/# |
Inter-server RPC requests |
socket.io-response#<uid># |
Directed RPC responses |
- BoltQ server >= 1.0.0
- Socket.IO >= 4.0.0
- Node.js >= 18 (or
wspackage for WebSocket support)