我有这个简单的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/