CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-socket-io--redis-adapter

Redis adapter for Socket.IO that enables broadcasting packets between multiple Socket.IO servers through Redis pub/sub functionality

Pending
Overview
Eval results
Files

utilities.mddocs/

Utility Functions

Cross-client compatibility utilities for Redis operations and binary data handling. These functions provide a unified interface for working with different Redis client libraries and managing message encoding.

Capabilities

Binary Data Detection

Utility function for detecting binary data in objects, used for message encoding decisions.

/**
 * Checks if an object contains binary data (ArrayBuffer, TypedArray, etc.)
 * @param obj - Object to check for binary data
 * @param toJSON - Whether to check toJSON method output (internal use)
 * @returns True if object contains binary data
 */
function hasBinary(obj: any, toJSON?: boolean): boolean;

Usage Examples:

import { hasBinary } from "@socket.io/redis-adapter";

// Check various data types
console.log(hasBinary("string")); // false
console.log(hasBinary(123)); // false
console.log(hasBinary({ text: "hello" })); // false

// Binary data detection
console.log(hasBinary(Buffer.from("hello"))); // true
console.log(hasBinary(new Uint8Array([1, 2, 3]))); // true
console.log(hasBinary(new ArrayBuffer(10))); // true

// Mixed data structures
console.log(hasBinary({
  text: "hello",
  data: Buffer.from("binary")
})); // true

console.log(hasBinary([
  "string",
  { buffer: new Uint8Array([1, 2, 3]) }
])); // true

Sharded Redis Operations

Cross-client utilities for Redis sharded pub/sub operations, providing compatibility across different Redis client versions.

/**
 * Subscribe to a sharded Redis channel with cross-client compatibility
 * @param redisClient - Redis client instance (redis v3, v4, or ioredis)
 * @param channel - Channel name to subscribe to
 * @param handler - Message handler function receiving raw message and channel
 */
function SSUBSCRIBE(
  redisClient: any,
  channel: string,
  handler: (rawMessage: Buffer, channel: Buffer) => void
): void;

/**
 * Unsubscribe from sharded Redis channel(s)
 * @param redisClient - Redis client instance
 * @param channel - Channel name or array of channel names to unsubscribe from
 */
function SUNSUBSCRIBE(redisClient: any, channel: string | string[]): void;

/**
 * Publish message to sharded Redis channel
 * @param redisClient - Redis client instance
 * @param channel - Channel name to publish to
 * @param payload - Message payload (string or binary data)
 * @returns Promise resolving to publish result
 */
function SPUBLISH(
  redisClient: any,
  channel: string,
  payload: string | Uint8Array
): Promise<any>;

Usage Examples:

import { createClient } from "redis";
import { SSUBSCRIBE, SUNSUBSCRIBE, SPUBLISH } from "@socket.io/redis-adapter";

const client = createClient();
await client.connect();

// Subscribe to sharded channel
SSUBSCRIBE(client, "game-events", (message, channel) => {
  console.log(`Received on ${channel}:`, message.toString());
});

// Publish to sharded channel
await SPUBLISH(client, "game-events", JSON.stringify({
  type: "player-joined",
  playerId: 123
}));

// Unsubscribe from single channel
SUNSUBSCRIBE(client, "game-events");

// Unsubscribe from multiple channels
SUNSUBSCRIBE(client, ["channel1", "channel2", "channel3"]);

Redis Pub/Sub Information

Utility for querying Redis pub/sub information across different client types and cluster configurations.

/**
 * Execute PUBSUB commands across different Redis client types and topologies
 * Handles standalone Redis, Redis clusters, and different client libraries
 * @param redisClient - Redis client instance (any supported type)
 * @param arg - PUBSUB command argument (e.g., "NUMSUB", "SHARDNUMSUB")
 * @param channel - Channel name to query
 * @returns Promise resolving to numeric result (subscriber count, etc.)
 */
function PUBSUB(redisClient: any, arg: string, channel: string): Promise<number>;

Usage Examples:

import { createClient, createCluster } from "redis";
import { PUBSUB } from "@socket.io/redis-adapter";

// With standalone Redis client
const standaloneClient = createClient();
await standaloneClient.connect();

// Get subscriber count for regular channel
const subscriberCount = await PUBSUB(standaloneClient, "NUMSUB", "my-channel");
console.log(`Subscribers: ${subscriberCount}`);

// Get subscriber count for sharded channel
const shardedCount = await PUBSUB(standaloneClient, "SHARDNUMSUB", "sharded-channel");
console.log(`Sharded subscribers: ${shardedCount}`);

// With Redis cluster
const clusterClient = createCluster({
  rootNodes: [
    { url: "redis://localhost:7000" },
    { url: "redis://localhost:7001" }
  ]
});
await clusterClient.connect();

// Automatically handles cluster topology
const clusterCount = await PUBSUB(clusterClient, "NUMSUB", "cluster-channel");
console.log(`Cluster subscribers: ${clusterCount}`);

ioredis Compatibility

The utilities also work with ioredis clients:

import { Redis, Cluster } from "ioredis";
import { PUBSUB } from "@socket.io/redis-adapter";

// ioredis standalone
const ioredisClient = new Redis();
const count1 = await PUBSUB(ioredisClient, "NUMSUB", "channel");

// ioredis cluster
const ioredisCluster = new Cluster([
  { host: "localhost", port: 7000 },
  { host: "localhost", port: 7001 }
]);
const count2 = await PUBSUB(ioredisCluster, "NUMSUB", "channel");

Redis Response Parsing

Helper functions for parsing Redis command responses, exported for advanced use cases.

/**
 * Parse NUMSUB command response from Redis
 * @param res - Raw Redis response array containing channel and subscriber count
 * @returns Parsed subscriber count as integer
 */
function parseNumSubResponse(res: any[]): number;

/**
 * Sum an array of numeric values
 * @param values - Array of numbers to sum
 * @returns Total sum of all values
 */
function sumValues(values: number[]): number;

Usage Examples:

import { parseNumSubResponse, sumValues } from "@socket.io/redis-adapter";

// Parse Redis NUMSUB response
const redisResponse = ["my-channel", "5"];
const subscriberCount = parseNumSubResponse(redisResponse);
console.log(`Subscribers: ${subscriberCount}`); // Subscribers: 5

// Sum cluster node responses
const clusterCounts = [3, 5, 2, 8];
const totalSubscribers = sumValues(clusterCounts);
console.log(`Total: ${totalSubscribers}`); // Total: 18

Client Detection

The utilities automatically detect Redis client types and versions:

  • redis v4+: Detected by presence of sSubscribe method
  • redis v3: Legacy callback-based API
  • ioredis: Detected by constructor name or isCluster property
  • Clusters: Automatically detected and handled appropriately

Error Handling

The utilities include built-in error handling for common scenarios:

  • Malformed Messages: Invalid JSON or MessagePack data is ignored
  • Connection Errors: Client connection issues are handled gracefully
  • Version Compatibility: Automatic fallback for different client versions

Binary Data Support

The hasBinary function supports comprehensive binary data detection:

  • Native Types: ArrayBuffer, all TypedArray variants
  • Node.js Types: Buffer objects
  • Nested Objects: Recursively checks object properties and array elements
  • JSON Serializable: Checks toJSON() output if present
  • Performance: Optimized for common cases, early returns for primitives

Install with Tessl CLI

npx tessl i tessl/npm-socket-io--redis-adapter

docs

index.md

regular-adapter.md

sharded-adapter.md

utilities.md

tile.json