MongoDB 适配器
这个怎么运作
MongoDB 适配器依赖于 MongoDB 的变更流(因此需要副本集或分片集群)。
每个发送给多个客户的数据包 (例如 io.to("room1").emit() 或 socket.broadcast.emit()) 是:
- 发送到连接到当前服务器的所有匹配客户端
- 插入到 MongoDB capped 集合中,并由集群的其他 Socket.IO 服务器接收

这个适配器的源代码可以在这里找到。
安装
npm install @socket.io/mongo-adapter mongodb
对于 TypeScript 用户,您可能还需要@types/mongodb.
用法
有两种方法可以清理适配器创建的 MongoDB 文档:
使用 capped collection
const { Server } = require("socket.io");
const { createAdapter } = require("@socket.io/mongo-adapter");
const { MongoClient } = require("mongodb");
const DB = "mydb";
const COLLECTION = "socket.io-adapter-events";
const io = new Server();
const mongoClient = new MongoClient("mongodb://localhost:27017/?replicaSet=rs0", {
  useUnifiedTopology: true,
});
const main = async () => {
  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);
}
main();
使用 TTL index
const { Server } = require("socket.io");
const { createAdapter } = require("@socket.io/mongo-adapter");
const { MongoClient } = require("mongodb");
const DB = "mydb";
const COLLECTION = "socket.io-adapter-events";
const io = new Server();
const mongoClient = new MongoClient("mongodb://localhost:27017/?replicaSet=rs0", {
  useUnifiedTopology: true,
});
const main = async () => {
  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);
}
main();
配置
| 配置项 | 描述 | 默认值 | 添加于 | 
|---|---|---|---|
| uid | 此节点的 ID | 一个随机的 id | v0.1.0 | 
| requestsTimeout | 服务器间请求的超时时间,例如 fetchSockets()或serverSideEmit() | 5000 | v0.1.0 | 
| heartbeatInterval | 两次心跳之间的毫秒数 | 5000 | v0.1.0 | 
| heartbeatTimeout | 在我们考虑节点关闭之前没有心跳的毫秒数 | 10000 | v0.1.0 | 
| addCreatedAtField | 是否为每个 MongoDB 文档添加一个 createdAt字段 | false | v0.2.0 | 
常见问题
- 使用 MongoDB 适配器时是否还需要启用粘性会话?
是的。否则将导致 HTTP 400 响应(您到达的服务器不知道 Socket.IO 会话)。
更多信息可以在这里找到。
- 当 MongoDB 集群宕机时会发生什么?
如果与 MongoDB 集群的连接被切断,行为将取决于MongoDB 客户端选项bufferMaxEntries的值:
- 如果其值为-1(默认),则数据包将被缓冲直到重新连接。
- 如果其值为0,则数据包将仅发送到连接到当前服务器的客户端。
文档: http://mongodb.github.io/node-mongodb-native/3.6/api/global.html#MongoClientOptions
最新版本
- 0.3.0(Feb 2023): GitHub release / diff
- 0.2.1(May 2022): GitHub release / diff
- 0.2.0(Apr 2022): GitHub release / diff
- 0.1.0(Jun 2021): GitHub release
Emitter
MongoDB 发射器允许从另一个 Node.js 进程向连接的客户端发送数据包:

安装
npm install @socket.io/mongo-emitter mongodb
用法
const { Emitter } = require("@socket.io/mongo-emitter");
const { MongoClient } = require("mongodb");
const mongoClient = new MongoClient("mongodb://localhost:27017/?replicaSet=rs0", {
  useUnifiedTopology: true,
});
const main = async () => {
  await mongoClient.connect();
  const mongoCollection = mongoClient.db("mydb").collection("socket.io-adapter-events");
  const emitter = new Emitter(mongoCollection);
  setInterval(() => {
    emitter.emit("ping", new Date());
  }, 1000);
}
main();
请参阅此处的备忘单。