DocumentationCore Protocol

@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 ioredis

Basic 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

OptionTypeDefaultDescription
hoststring"localhost"Redis host
portnumber6379Redis port
passwordstringRedis AUTH password
dbnumber0Database index
keyPrefixstring"pp:"Prefix for all Redis keys and channels
registryPPSchemaRegistrySchema registry for binary type IDs. Must match the server's registry.
onError(err) => voidRedis connection error handler

Binary Wire Format

Each Redis pub/sub message is a compact binary buffer (big-endian):

FieldSizeNotes
excludeLenuint8Byte length of excludeClientId (0 = no exclude)
excludeIdN bytes utf8The client ID to exclude from delivery
typeIduint160 = string type, >0 = schema registry ID
typeLen + typeuint16 + utf8Only present when typeId = 0
payloadrestJSON 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