๐Ÿ“ฆ socketio / socket.io-postgres-adapter

The Socket.IO Postgres adapter, allowing to broadcast events between several Socket.IO servers

โ˜… 24 stars โ‘‚ 9 forks ๐Ÿ‘ 24 watching โš–๏ธ MIT License
postgrespostgresqlsocket-iowebsocket
๐Ÿ“ฅ Clone https://github.com/socketio/socket.io-postgres-adapter.git
HTTPS git clone https://github.com/socketio/socket.io-postgres-adapter.git
SSH git clone git@github.com:socketio/socket.io-postgres-adapter.git
CLI gh repo clone socketio/socket.io-postgres-adapter
Damien Arrachequesne Damien Arrachequesne chore(release): 0.5.0 a9300c1 2 months ago ๐Ÿ“ History
๐Ÿ“‚ main View all commits โ†’
๐Ÿ“ .github
๐Ÿ“ assets
๐Ÿ“ lib
๐Ÿ“ test
๐Ÿ“„ .gitignore
๐Ÿ“„ CHANGELOG.md
๐Ÿ“„ compose.yaml
๐Ÿ“„ LICENSE
๐Ÿ“„ package-lock.json
๐Ÿ“„ package.json
๐Ÿ“„ README.md
๐Ÿ“„ tsconfig.json
๐Ÿ“„ README.md

Socket.IO Postgres adapter

The @socket.io/postgres-adapter package allows broadcasting packets between multiple Socket.IO servers.

Diagram of Socket.IO packets forwarded through PostgreSQL

Table of contents

Supported features

Featuresocket.io versionSupport
Socket management4.0.0:whitecheckmark: YES (since version 0.1.0)
Inter-server communication4.1.0:whitecheckmark: YES (since version 0.1.0)
Broadcast with acknowledgements4.5.0:whitecheckmark: YES (since version 0.3.0)
Connection state recovery4.6.0:x: NO

Installation

npm install @socket.io/postgres-adapter

Usage

Standalone

import { Server } from "socket.io";
import { createAdapter } from "@socket.io/postgres-adapter";
import pg from "pg";

const io = new Server();

const pool = new pg.Pool({
  user: "postgres",
  host: "localhost",
  database: "postgres",
  password: "changeit",
  port: 5432,
});

pool.query(`
  CREATE TABLE IF NOT EXISTS socket_io_attachments (
      id          bigserial UNIQUE,
      created_at  timestamptz DEFAULT NOW(),
      payload     bytea
  );
`);

pool.on("error", (err) => {
  console.error("Postgres error", err);
});

io.adapter(createAdapter(pool));
io.listen(3000);

With Node.js cluster

import cluster from "node:cluster";
import { createServer } from "node:http";
import { availableParallelism } from "node:os";
import { Server } from "socket.io";
import { setupPrimary } from "@socket.io/postgres-adapter"
import { createAdapter } from "@socket.io/cluster-adapter";
import pg from "pg";

if (cluster.isPrimary) {
  const pool = new pg.Pool({
    user: "postgres",
    password: "changeit",
  });
  
  await pool.query(`
    CREATE TABLE IF NOT EXISTS socket_io_attachments (
        id          bigserial UNIQUE,
        created_at  timestamptz DEFAULT NOW(),
        payload     bytea
    );
  `);

  setupPrimary(pool);

  for (let i = 0; i < availableParallelism(); i++) {
    cluster.fork();
  }
} else {
  const io = new Server({
    adapter: createAdapter(),
  });

  io.on("connection", (socket) => {
    /* ... */
  });

  io.listen(3000);
}

Options

NameDescriptionDefault value
channelPrefixThe prefix of the notification channel.socket.io
tableNameThe name of the table for payloads over the 8000 bytes limit or containing binary data.socket_io_attachments
payloadThresholdThe threshold for the payload size in bytes (see https://www.postgresql.org/docs/current/sql-notify.html).8_000
cleanupIntervalNumber of ms between two cleanup queries.30_000
heartbeatIntervalThe number of ms between two heartbeats.5_000
heartbeatTimeoutThe number of ms without heartbeat before we consider a node down.10_000

License

MIT