Clustering (Redis)
Scaling your OCPP server with Redis.
For multi-instance deployments (e.g., Kubernetes, load balancers), you need to synchronize state and events across server instances. ocpp-ws-io provides a RedisAdapter for this purpose.
Installation
You need to allow ocpp-ws-io to access your Redis client. The adapter is compatible with ioredis and node-redis.
Usage
Usage with ioredis (Recommended)
import { OCPPServer } from "ocpp-ws-io";
import { RedisAdapter } from "ocpp-ws-io/adapters/redis";
import Redis from "ioredis";
const server = new OCPPServer({ protocols: ["ocpp2.0.1"] });
// Create two clients: one for publishing, one for subscribing
const pub = new Redis(process.env.REDIS_URL);
const sub = new Redis(process.env.REDIS_URL);
server.setAdapter(
new RedisAdapter({
pubClient: pub,
subClient: sub,
prefix: "ocpp-cluster:", // Optional custom prefix
}),
);
server.on("client", (client) => {
console.log(`${client.identity} connected`);
});
await server.listen(3000);Usage with node-redis
import { createClient } from "redis";
import { OCPPServer } from "ocpp-ws-io";
import { RedisAdapter } from "ocpp-ws-io/adapters/redis";
const server = new OCPPServer({ protocols: ["ocpp2.0.1"] });
const pub = createClient({ url: process.env.REDIS_URL });
const sub = pub.duplicate();
await Promise.all([pub.connect(), sub.connect()]);
const adapter = new RedisAdapter({
pubClient: pub,
subClient: sub,
});
server.setAdapter(adapter);
await server.listen(3000);How it works
When you use the RedisAdapter, the following happens:
- Broadcasts: If you call
server.broadcast(), the message is published to Redis and sent by all server instances to their connected clients. - Loop Prevention: The sender node's ID is attached to the message, ensuring it doesn't re-broadcast to itself.
- State Sync: (If implemented features require it) Shared state usage leverages Redis.
Note: Pure point-to-point calls (client.call) still route directly to the connected socket. The clusters are primarily for broadcast and discovery scenarios.