简体   繁体   English

处理多个实例上的 websocket 连接

[英]handle websocket connections on multiple instances

I need to understand the concept of handling websockets on multiple instances so that it could be shared across all the instances.我需要了解在多个实例上处理 websockets 的概念,以便它可以在所有实例之间共享。 For eg I have three nodes running which is being connected by the load balancer.例如,我有三个节点正在运行,这些节点由负载平衡器连接。 On receiving the data which needs to be emit on the specific socket.在接收需要在特定套接字上发出的数据时。 My initial idea was to create a hashmap or json objects to holds the websocket connections.我最初的想法是创建一个 hashmap 或 json 对象来保存 websocket 连接。 But I realize that this couldn't be done in this way as it will be only specific to its particular instance.但我意识到这不能以这种方式完成,因为它只会特定于其特定实例。 If I will receive the data on any of the instances then most of the data will not be going to emit on that websocket connection as it doesn't know on which instance the websocket is created.如果我将在任何实例上接收数据,那么大部分数据将不会在该 websocket 连接上发出,因为它不知道 websocket 是在哪个实例上创建的。 Is there a good way to handle websocket connections so that it could be shared on all instances.是否有一种处理 websocket 连接的好方法,以便它可以在所有实例上共享。 My ideas was to use redis or postgres sql database because they are shared among all the instances.我的想法是使用 redis 或 postgres sql 数据库,因为它们在所有实例之间共享。

Also I have tried the postgres solution to store the websocket connection but when I save the connection it says我也尝试过使用 postgres 解决方案来存储 websocket 连接,但是当我保存连接时,它说

TypeError: Converting circular structure to JSON类型错误:将圆形结构转换为 JSON

Is there some good solution to handle websocket connections that could be shared among all instances.是否有一些好的解决方案来处理可以在所有实例之间共享的 websocket 连接。 If database is a good solution how can I resolve如果数据库是一个很好的解决方案,我该如何解决

TypeError: Converting circular structure to JSON类型错误:将圆形结构转换为 JSON

I guess the thing you are looking for are Adapters , and it's being documented relatively well in the official socket.io documentation ( /v4/adapter/ ).我猜你正在寻找的东西是Adapters ,它在官方 socket.io 文档( /v4/adapter/ )中有相对较好的记录。

When scaling to multiple Socket.IO servers, you will need to replace the default in-memory adapter by another implementation, so the events are properly routed to all clients.当扩展到多个 Socket.IO 服务器时,您需要用另一个实现替换默认的内存中适配器,以便将事件正确路由到所有客户端。

You have several official adapters you can choose from :您有多种官方适配器可供选择:

  • Redis adapter Redis 适配器
  • MongoDB adapter MongoDB 适配器
  • Postgres adapter Postgres 适配器
  • Cluster adapter集群适配器

Here is an example using the MongoDB Adapter :以下是使用MongoDB Adapter 的示例:

npm install @socket.io/mongo-adapter mongodb
const { Server } = require("socket.io");
const { createAdapter } = require("@socket.io/mongo-adapter");
const { MongoClient } = require("mongodb");

// DATABASE CONNECTION
const DB = "mydb";
const COLLECTION = "socket.io-adapter-events";
const mongoClient = new MongoClient("mongodb://localhost:27017/?replicaSet=rs0", {
  useUnifiedTopology: true,
});

const io = new Server();

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);

  // HERE COMES THE IMPORTANT PART :)
  // CREATE MONGO DB ADAPTER AND USE IT 
  io.adapter(createAdapter(mongoCollection));
  io.listen(3000);
}

main();

The adapter then will take care of the rest.然后适配器会处理剩下的事情。 Every packet that is sent to multiple clients (eg io.to("room1").emit() or socket.broadcast.emit() ) will be发送到多个客户端的每个数据包(例如io.to("room1").emit()socket.broadcast.emit() )将是

  • sent to all matching clients connected to the current server发送到连接到当前服务器的所有匹配客户端
  • inserted in a MongoDB capped collection, and received by the other Socket.IO servers of the cluster插入到 MongoDB 上限集合中,并由集群的其他 Socket.IO 服务器接收

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM