By default, LocalAdapter manages room broadcasting in single-process memory. To scale out across multiple Docker containers or Kubernetes pods, implement SocketAdapter.
Each server instance must be assigned a unique nodeId. The engine automatically ignores messages originating from its own nodeId to avoid duplicate loopback deliveries.
1import { SocketAdapter, AdapterMessage, subatomPulse } from "subatom-pulse";1import Redis from "ioredis";11export class RedisClusterAdapter implements SocketAdapter {1 private readonly channel = "pulse:cluster:bus";21 constructor(1 private readonly pub: Redis,1 private readonly sub: Redis1 ) {}31 public async publish(message: AdapterMessage): Promise<void> {1 await this.pub.publish(this.channel, JSON.stringify(message));1 }41 public async subscribe(handler: (message: AdapterMessage) => void): Promise<() => void> {1 await this.sub.subscribe(this.channel);51 const onMsg = (chan: string, raw: string) => {1 if (chan !== this.channel) return;1 try {1 const parsed = JSON.parse(raw) as AdapterMessage;1 handler(parsed);1 } catch {1 // Discard malformed bridge frames1 }1 };61 this.sub.on("message", onMsg);1 return () => {1 this.sub.off("message", onMsg);1 this.sub.unsubscribe(this.channel);2 };2 }71 public async close(): Promise<void> {1 await this.pub.quit();1 await this.sub.quit();3 }1}81// Instantiate with unique cluster node ID1const io = subatomPulse({1 nodeId: process.env.POD_NAME ?? `node-${process.pid}`,1 adapter: new RedisClusterAdapter(new Redis(), new Redis())1});