@painda/redis
Binary-native Redis adapter for horizontal scaling. Unlike Socket.io's Redis adapter which uses JSON.stringify for every inter-node message, PP uses a compact binary wire format with optional schema registry integration.
Installation
npm install @painda/redis ioredisBasic Setup
import { PPServer } from "@painda/core";
import { RedisAdapter } from "@painda/redis";
const server = new PPServer({
port: 3000,
adapter: new RedisAdapter({
host: "localhost",
port: 6379,
// password: "...",
// db: 0,
// keyPrefix: "pp:", // default
onError: (err) => console.error("[Redis]", err),
}),
});With Schema Registry (Maximum Compression)
Pass the same schema registry to both the server and the adapter. Registered event types are encoded as 2-byte IDs in Redis pub/sub instead of full strings.
import { PPServer, PPSchemaRegistry, structSerializer } from "@painda/core";
import { RedisAdapter } from "@painda/redis";
const registry = new PPSchemaRegistry();
registry.register("player:move", structSerializer(1, [
{ name: "x", type: "float32" },
{ name: "y", type: "float32" },
]));
const server = new PPServer({
port: 3000,
registry,
adapter: new RedisAdapter({ host: "redis-host", registry }),
});
// "player:move" → 2 bytes in Redis
// vs Socket.io: JSON.stringify({ event: "player:move", ... })Options
| Option | Type | Default | Description |
|---|---|---|---|
| host | string | "localhost" | Redis host |
| port | number | 6379 | Redis port |
| password | string | — | Redis AUTH password |
| db | number | 0 | Database index |
| keyPrefix | string | "pp:" | Prefix for all Redis keys and channels |
| registry | PPSchemaRegistry | — | Schema registry for binary type IDs. Must match the server's registry. |
| onError | (err) => void | — | Redis connection error handler |
Binary Wire Format
Each Redis pub/sub message is a compact binary buffer (big-endian):
| Field | Size | Notes |
|---|---|---|
| excludeLen | uint8 | Byte length of excludeClientId (0 = no exclude) |
| excludeId | N bytes utf8 | The client ID to exclude from delivery |
| typeId | uint16 | 0 = string type, >0 = schema registry ID |
| typeLen + type | uint16 + utf8 | Only present when typeId = 0 |
| payload | rest | JSON bytes (no registry) or schema-binary (with registry) |
Architecture Notes
The adapter internally uses two ioredis clients: one for commands and publishing (pubClient), and one dedicated to subscribe mode (subClient). This is required because ioredis in subscribe mode cannot issue any other commands.
Room membership is stored in Redis Sets: pp:room:{room} and reverse-lookup pp:client:{id}:rooms. Pub/sub channels use pp:ch:{channel} to avoid key collisions.
See also: Horizontal Scaling · @painda/core