MongoDB 适配器

这个怎么运作

MongoDB 适配器依赖于 MongoDB 的变更流(因此需要副本集或分片集群)。

每个发送给多个客户的数据包 (例如 io.to("room1").emit()socket.broadcast.emit()) 是:

  • 发送到连接到当前服务器的所有匹配客户端
  • 插入到 MongoDB capped 集合中,并由集群的其他 Socket.IO 服务器接收

Diagram of how the MongoDB adapter works

这个适配器的源代码可以在这里找到。

安装

  1. npm install @socket.io/mongo-adapter mongodb

对于 TypeScript 用户,您可能还需要@types/mongodb.

用法

有两种方法可以清理适配器创建的 MongoDB 文档:

使用 capped collection

  1. const { Server } = require("socket.io");
  2. const { createAdapter } = require("@socket.io/mongo-adapter");
  3. const { MongoClient } = require("mongodb");
  4. const DB = "mydb";
  5. const COLLECTION = "socket.io-adapter-events";
  6. const io = new Server();
  7. const mongoClient = new MongoClient("mongodb://localhost:27017/?replicaSet=rs0");
  8. const main = async () => {
  9. await mongoClient.connect();
  10. try {
  11. await mongoClient.db(DB).createCollection(COLLECTION, {
  12. capped: true,
  13. size: 1e6
  14. });
  15. } catch (e) {
  16. // collection already exists
  17. }
  18. const mongoCollection = mongoClient.db(DB).collection(COLLECTION);
  19. io.adapter(createAdapter(mongoCollection));
  20. io.listen(3000);
  21. }
  22. main();

使用 TTL index

  1. const { Server } = require("socket.io");
  2. const { createAdapter } = require("@socket.io/mongo-adapter");
  3. const { MongoClient } = require("mongodb");
  4. const DB = "mydb";
  5. const COLLECTION = "socket.io-adapter-events";
  6. const io = new Server();
  7. const mongoClient = new MongoClient("mongodb://localhost:27017/?replicaSet=rs0");
  8. const main = async () => {
  9. await mongoClient.connect();
  10. const mongoCollection = mongoClient.db(DB).collection(COLLECTION);
  11. await mongoCollection.createIndex(
  12. { createdAt: 1 },
  13. { expireAfterSeconds: 3600, background: true }
  14. );
  15. io.adapter(createAdapter(mongoCollection, {
  16. addCreatedAtField: true
  17. }));
  18. io.listen(3000);
  19. }
  20. main();

配置

配置项描述默认值添加于
uid此节点的 ID一个随机的 idv0.1.0
requestsTimeout服务器间请求的超时时间,例如fetchSockets()serverSideEmit()5000v0.1.0
heartbeatInterval两次心跳之间的毫秒数5000v0.1.0
heartbeatTimeout在我们考虑节点关闭之前没有心跳的毫秒数10000v0.1.0
addCreatedAtField是否为每个 MongoDB 文档添加一个createdAt字段falsev0.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

最新版本

Emitter

MongoDB 发射器允许从另一个 Node.js 进程向连接的客户端发送数据包:

Diagram of how the MongoDB emitter works

安装

  1. npm install @socket.io/mongo-emitter mongodb

用法

  1. const { Emitter } = require("@socket.io/mongo-emitter");
  2. const { MongoClient } = require("mongodb");
  3. const mongoClient = new MongoClient("mongodb://localhost:27017/?replicaSet=rs0");
  4. const main = async () => {
  5. await mongoClient.connect();
  6. const mongoCollection = mongoClient.db("mydb").collection("socket.io-adapter-events");
  7. const emitter = new Emitter(mongoCollection);
  8. setInterval(() => {
  9. emitter.emit("ping", new Date());
  10. }, 1000);
  11. }
  12. main();

请参阅此处的备忘单。