Redis adapter for Socket.IO that enables broadcasting packets between multiple Socket.IO servers through Redis pub/sub functionality
—
Standard Redis adapter implementation for Socket.IO servers using traditional Redis pub/sub channels. Provides broadcasting, socket management, and inter-server communication capabilities.
Creates a Redis adapter factory function that can be used to configure Socket.IO servers.
/**
* Creates a Redis adapter factory function
* @param pubClient - Redis client used to publish messages
* @param subClient - Redis client used to receive messages (put in subscribed state)
* @param opts - Optional configuration options
* @returns Function that creates RedisAdapter instances for namespaces
*/
function createAdapter(
pubClient: any,
subClient: any,
opts?: Partial<RedisAdapterOptions>
): (nsp: any) => RedisAdapter;Usage Examples:
import { createClient } from "redis";
import { Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";
// With redis package
const pubClient = createClient({ url: "redis://localhost:6379" });
const subClient = pubClient.duplicate();
await Promise.all([
pubClient.connect(),
subClient.connect()
]);
const io = new Server({
adapter: createAdapter(pubClient, subClient, {
key: "my-app",
requestsTimeout: 10000
})
});
// With ioredis package
import { Redis } from "ioredis";
const pubClient = new Redis();
const subClient = pubClient.duplicate();
const io = new Server({
adapter: createAdapter(pubClient, subClient)
});Main adapter implementation that extends the base Socket.IO adapter with Redis functionality.
/**
* Redis adapter class providing multi-server broadcasting capabilities
*/
class RedisAdapter extends Adapter {
readonly uid: string;
readonly requestsTimeout: number;
readonly publishOnSpecificResponseChannel: boolean;
readonly parser: Parser;
/**
* Create a new RedisAdapter instance
* @param nsp - Socket.IO namespace
* @param pubClient - Redis client for publishing
* @param subClient - Redis client for subscribing
* @param opts - Configuration options
*/
constructor(
nsp: any,
pubClient: any,
subClient: any,
opts?: Partial<RedisAdapterOptions>
);
}Methods for broadcasting packets to other Socket.IO servers.
/**
* Broadcasts a packet to other servers
* @param packet - Packet to emit
* @param opts - Broadcasting options including rooms and flags
*/
broadcast(packet: any, opts: BroadcastOptions): void;
/**
* Broadcasts a packet with acknowledgement support
* @param packet - Packet to emit
* @param opts - Broadcasting options
* @param clientCountCallback - Called with total client count expecting acknowledgements
* @param ack - Called for each acknowledgement received
*/
broadcastWithAck(
packet: any,
opts: BroadcastOptions,
clientCountCallback: (clientCount: number) => void,
ack: (...args: any[]) => void
): void;Usage Examples:
// Basic broadcasting (handled automatically by Socket.IO)
io.emit("notification", { message: "Hello all servers!" });
// Broadcasting to specific rooms
io.to("room1").emit("message", "Hello room1!");
// Broadcasting with acknowledgements
io.timeout(5000).emit("ping", (err, responses) => {
if (err) {
console.error("Some clients did not acknowledge:", err);
} else {
console.log("All clients acknowledged:", responses);
}
});Methods for managing rooms and sockets across multiple servers.
/**
* Gets all rooms across all servers
* @returns Promise resolving to set of all room names
*/
allRooms(): Promise<Set<Room>>;
/**
* Fetches socket information from all servers
* @param opts - Options specifying which sockets to fetch
* @returns Promise resolving to array of socket information
*/
fetchSockets(opts: BroadcastOptions): Promise<any[]>;
/**
* Adds sockets to rooms across all servers
* @param opts - Options specifying which sockets to affect
* @param rooms - Array of room names to join
*/
addSockets(opts: BroadcastOptions, rooms: Room[]): void;
/**
* Removes sockets from rooms across all servers
* @param opts - Options specifying which sockets to affect
* @param rooms - Array of room names to leave
*/
delSockets(opts: BroadcastOptions, rooms: Room[]): void;
/**
* Disconnects sockets across all servers
* @param opts - Options specifying which sockets to disconnect
* @param close - Whether to close the underlying connection
*/
disconnectSockets(opts: BroadcastOptions, close: boolean): void;Usage Examples:
// Get all rooms across servers
const allRooms = await io.adapter.allRooms();
console.log("All rooms:", [...allRooms]);
// Fetch all sockets in a room across servers
const sockets = await io.in("room1").fetchSockets();
console.log(`Found ${sockets.length} sockets in room1`);
// Make all sockets in room1 join room2
io.in("room1").socketsJoin("room2");
// Disconnect all sockets in a room
io.in("room1").disconnectSockets();Methods for communication between Socket.IO server instances.
/**
* Emits an event to all other Socket.IO server instances
* @param packet - Array containing event name and arguments
*/
serverSideEmit(packet: any[]): void;
/**
* Gets the count of connected Socket.IO servers
* @returns Promise resolving to number of servers
*/
serverCount(): Promise<number>;Usage Examples:
// Emit to other servers without acknowledgement
io.serverSideEmit("hello", "world", 123);
// Emit to other servers with acknowledgement
io.serverSideEmit("ping", (err, responses) => {
if (err) {
console.error("Error:", err);
} else {
console.log("Responses from other servers:", responses);
}
});
// Get server count
const count = await io.engine.generateId =
const serverCount = await io.adapter.serverCount();
console.log(`Connected servers: ${serverCount}`);Methods for managing the adapter lifecycle.
/**
* Closes the adapter and cleans up Redis subscriptions
*/
close(): Promise<void> | void;interface RedisAdapterOptions {
/**
* The prefix for Redis Pub/Sub channels
* @default "socket.io"
*/
key: string;
/**
* Timeout for waiting for responses to requests (in milliseconds)
* @default 5000
*/
requestsTimeout: number;
/**
* Whether to publish responses to specific channels per requesting node
* @default false
*/
publishOnSpecificResponseChannel: boolean;
/**
* Message parser for encoding/decoding Redis messages
* @default notepack.io (MessagePack)
*/
parser: Parser;
}The adapter supports multiple Redis client libraries:
// Standalone Redis
import { createClient } from "redis";
const pubClient = createClient({ url: "redis://localhost:6379" });
const subClient = pubClient.duplicate();
// Redis Cluster
import { createCluster } from "redis";
const pubClient = createCluster({
rootNodes: [
{ url: "redis://localhost:7000" },
{ url: "redis://localhost:7001" },
{ url: "redis://localhost:7002" }
]
});
const subClient = pubClient.duplicate();// Standalone Redis
import { Redis } from "ioredis";
const pubClient = new Redis();
const subClient = pubClient.duplicate();
// Redis Cluster
import { Cluster } from "ioredis";
const pubClient = new Cluster([
{ host: "localhost", port: 7000 },
{ host: "localhost", port: 7001 },
{ host: "localhost", port: 7002 }
]);
const subClient = pubClient.duplicate();The following types are imported from the socket.io-adapter package:
// From socket.io-adapter
type Room = string | number;
interface BroadcastOptions {
rooms: Set<Room>;
except?: Set<Room>;
flags?: {
local?: boolean;
broadcast?: boolean;
binary?: boolean;
timeout?: number;
};
}Install with Tessl CLI
npx tessl i tessl/npm-socket-io--redis-adapter