javascript - 在 Sockets.IO Node.JS 中存储和访问客户端列表的最有效方法

标签 javascript node.js sockets websocket socket.io

我有这个简单的socket.io管理器,当用户连接时,他将被添加到在线客户端池中,并且当另一个客户端(例如客户端B)向客户端A发送消息时,它应该尝试仅当客户端位于池中时才发送该消息。目前我有这个:

var connectionMap = [];
const socketHandler = (io) => {
  io.on("connection", (socket) => {
    socket.id = "some_custom_id I define";
    connectionMap.push(socket);

    socket.on("textMessage", function (message) {
      connectionMap.forEach(function (connection, index) {
        if (connection.id == message.receiver_id)
          connection.emit("textMessage", message);
      });
    });

    socket.on("disconnect", function () {
      connectionMap.splice(connectionMap.indexOf(client), 1);
    });
  });
};

虽然这可能适用于用户数量较少的用例,但我正在寻找一种可以适当扩展而不会过多限制性能的解决方案。 (我无法想象 foreach 在跨平台发送的每条消息上运行数千个索引。)关于如何解决这个问题有什么想法吗?

最佳答案

对于connectionMap,您可以使用对象而不是数组。连接时,我们将 socket.id 设置为对象中的键,值可以为 true。在发送消息期间,我们可以直接在 connectionMap 中检查 message.receiver_id 是否存在。与使用数组作为 connectionMap 相比,这是一个显着的改进,因为在最坏的情况下,数组将花费 O(N) 时间,而使用对象(映射),您可以拥有恒定的时间 O(1)

var connectionMap = {};
const socketHandler = (io) => {
  io.on("connection", (socket) => {
    socket.id = "some_custom_id I define";
    connectionMap[socket.id] = socket;

    socket.on("textMessage", function (message) {
        if (connectionMap[message.receiver_id]) {
            connectionMap[message.receiver_id].emit("textMessage", message);
        }
    });

    socket.on("disconnect", function () {
        delete connectionMap[client];
    });
  });
};

或者您可以使用 Map

var connectionMap = new Map();
const socketHandler = (io) => {
  io.on("connection", (socket) => {
    socket.id = "some_custom_id I define";
    connectionMap.set(socket.id, socket);

    socket.on("textMessage", function (message) {
        if (connectionMap.has(message.receiver_id)) {
          connectionMap.get(message.receiver_id).emit("textMessage", message);
        }
    });

    socket.on("disconnect", function () {
        connectionMap.delete(client);
    });
  });
};

关于javascript - 在 Sockets.IO Node.JS 中存储和访问客户端列表的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63038016/

相关文章:

node.js - 如何使用 Electron 运行tensorflow.js?

node.js - 在 NodeJS 后端使用 JWT 和 Active Directory 身份验证

java - Java socket编程中如何实现客户端到服务器的持续交互

javascript - 为事件创建自己的对象以在代码完成中获取它有哪些优点/缺点?

javascript - 将输入值追加到元素中

javascript - Pace.JS Qtip 如何忽略 Pace Animation

javascript - 选择框上的 Angularjs ngKeyup 不起作用

node.js - 使用 AMQP.Node 的 RabbitMQ 和 Node 中未使用死信消息

sockets - 如何使用NodeJS将监听一个端口的WebSocket连接到监听另一个端口的Net socket?

java - 接收整数序列的服务器