Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@socket.io/mongo-adapter

socketio59.1kMIT0.3.2TypeScript support: included

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

socket.io, mongodb, mongo, adapter

readme

Socket.IO MongoDB adapter

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

<picture> <source media="(prefers-color-scheme: dark)" srcset="./assets/adapter_dark.png"> Diagram of Socket.IO packets forwarded through MongoDB </picture>

Unlike the existing socket.io-adapter-mongo package which uses tailable cursors, this package relies on change streams and thus requires a replica set or a sharded cluster.

Supported features:

Related packages:

Table of contents

Installation

npm install @socket.io/mongo-adapter mongodb

Usage

Broadcasting packets within a Socket.IO cluster is achieved by creating MongoDB documents and using a change stream on each Socket.IO server.

There are two ways to clean up the documents in MongoDB:

Usage with a capped collection

import { Server } from "socket.io";
import { createAdapter } from "@socket.io/mongo-adapter";
import { MongoClient } from "mongodb";

const DB = "mydb";
const COLLECTION = "socket.io-adapter-events";

const io = new Server();

const mongoClient = new MongoClient("mongodb://localhost:27017/?replicaSet=rs0");

await mongoClient.connect();

try {
  await mongoClient.db(DB).createCollection(COLLECTION, {
    capped: true,
    size: 1e6
  });
} catch (e) {
  // collection already exists
}
const mongoCollection = mongoClient.db(DB).collection(COLLECTION);

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

Usage with a TTL index

import { Server } from "socket.io";
import { createAdapter } from "@socket.io/mongo-adapter";
import { MongoClient } from "mongodb";

const DB = "mydb";
const COLLECTION = "socket.io-adapter-events";

const io = new Server();

const mongoClient = new MongoClient("mongodb://localhost:27017/?replicaSet=rs0");

await mongoClient.connect();

const mongoCollection = mongoClient.db(DB).collection(COLLECTION);

await mongoCollection.createIndex(
  { createdAt: 1 },
  { expireAfterSeconds: 3600, background: true }
);

io.adapter(createAdapter(mongoCollection, {
  addCreatedAtField: true
}));

io.listen(3000);

Known errors

  • MongoError: The $changeStream stage is only supported on replica sets

Change streams are only available for replica sets and sharded clusters.

More information here.

Please note that, for development purposes, you can have a single MongoDB process acting as a replica set by running rs.initiate() on the node.

  • TypeError: this.mongoCollection.insertOne is not a function

You probably passed a MongoDB client instead of a MongoDB collection to the createAdapter method.

License

MIT

changelog

History

Release notes

0.3.2 (2024-01-23)

Bug Fixes

  • add support for AWS DocumentDB (#21) (0c80f7f)
  • ensure CSR works with a capped collection (d3fa038)
  • exclude offline nodes when calling serverCount() (e2fb8c2)

0.3.1 (2024-01-10)

Bug Fixes

  • add support for mongodb@6 (1a04885)
  • properly handle promise rejections (075216f)

0.3.0 (2023-02-23)

Features

Connection state recovery

This adapter is now compatible with the connection state recovery feature, which was added in `socket.io@4.6.0`.

Reference: https://socket.io/docs/v4/connection-state-recovery

Added in 02e4d57.

Resume token

Upon reconnection to the MongoDB server, the client will now try to resume the stream at the last offset it has processed.

If the MongoDB client is disconnected for too long and its token is no longer valid, then the Socket.IO clients connected to this server may miss some packets (which was the previous behavior).

Added in e77063b.

0.2.1 (2022-05-03)

Bug Fixes

  • properly handle invalidate events (938674d)

0.2.0 (2022-04-27)

Features

  • add an option to use a TTL index (#4) (7fdbb25)

The addCreatedAtField option allows to use a TTL index instead of a capped collection, which is slightly less efficient but more predictable.

  • broadcast and expect multiple acks (e87a0ce)

This feature was added in `socket.io@4.5.0`:

io.timeout(1000).emit("some-event", (err, responses) => {
  // ...
});

Thanks to this change, it will now work with multiple Socket.IO servers.

  • use a single stream for all namespaces (9b5f4c8)

The adapter will now create one single MongoDB stream for all namespaces, instead of one per namespace, which could lead to performance issues.

0.1.0 (2021-06-01)

Initial commit