在构建聊天机智 Socket.io 时,我应该使用命名空间吗?



我正在构建一个平台,多个用户可以相互交互,并在另一个用户以某种方式与自己交互时收到通知。例如,发送消息、发送请求或更新服务器上的某些协作对象。这里没什么特别的。 因此,我喜欢在具有 express 的节点服务器上使用 Socket.io(前端在角度 7 中),以尽可能实时地保持用户体验。

我想知道我是否真的需要引入命名空间和房间,因为我当前的实现应该运行良好。你能告诉我,如果我的实现类型有问题吗?

我正在使用某种套接字连接存储作为 Map,我所有活动的套接字连接都在那里。这是我的服务器端实现的示例:

// <userId, socket>
var Connections = new Map();
removeConnection = function(socket) {
console.log("removing User with Id = " + socket.userId);
Connections.delete(socket.userId);
} 
io.on('connection', (socket) => {
socket.on('register', (userId) => {
// do some authentication here..
socket.userId = userId;
Connections.set(userId, socket);
console.log("User registered with id " + userId);
});
socket.on('disconnect', () => {
removeConnection(socket);
});
socket.on('new_message', (data) => {
// persist data in DB and so on..
socket.emit('new_message', data);
var receiver = Connections.get(data.receiverId);    
// if receiver is online send message
if(receiver) {
receiver.emit('new_message', data);
}
});
});

如果您没有使用任何收件人选择(例如单个收件人或命名空间/房间),则每条消息都将传递到每个客户端。假设每个客户端在连接后都会发送一条"hello"消息。"你好"消息的数量将随着客户数量的增加呈指数级增长。

根据您计划扩展应用程序的大小,这可能会导致大量流量:n 条消息会导致 n² 事务...1000 个用户每人发送 1 条消息已经是 1.000.000 个事务。

若要使通信更高效,可以执行以下任一步骤:

发送给
  • 单个用户的直接消息应仅发送给该用户,而不是整个平台上的广播。 您可以使用 connection.emit("消息")命令执行此操作。 io.emit("消息")将发送到每个连接的客户端

  • 有关
  • 并非所有用户都感兴趣的特定主题的消息可以使用"房间"来实现。 任何用户都可以订阅任意数量的房间来接收这些通知。 所有其他邮件都不会被这些邮件发送垃圾邮件。 (https://socket.io/docs/rooms-and-namespaces/)

另一个问题可能是隐私...如果用户 A 向用户 B 发送消息,那么您不希望用户 C、D、E.。也接收该广播。即使您的客户过滤掉不适合用户的消息,信息仍然会以纯文本形式发送给所有人,我认为这是不必要的隐私泄露。

这里有一个关于收件人选择和发送邮件的不同方法的很棒的备忘单: https://socket.io/docs/emit-cheatsheet/

您的代码接收来自任何连接的客户端的消息,并仅将其转发给相应的收件人(如果在映射中找到)。这对于用户之间的直接消息传递来说很好。如果要广播某些协作项目的更新信息,则应使用如上所述的房间和命名空间。

最新更新