【发布时间】:2019-08-31 06:46:49
【问题描述】:
我有一个使用 Socket.io 向客户端发出事件的 node.js 服务器。当连接事件发生时,新的套接字会根据连接用户的 ID 放置在房间中,该 ID 是使用来自socket.headers.handshake.cookie 的会话 ID cookie 获得的。我知道这部分工作正常,因为我可以设置断点并检查 io.sockets.adapter.rooms 并查看这个房间:
所以,房间里显然只有一个插座。同样在此断点处暂停时,以下表达式:userID.toString() 的计算结果为:"5cd6201acb0d5f23e465cb84"。所以,这个表达式应该可以用来获取里面有那个插座的房间。然后,直接在断点之后,执行这段代码:
io.of('/').in(userID.toString()).emit('notification', notifHTML);
因此,我希望通知事件仅被发送到该房间中由该表达式标识的一个套接字。通知事件由客户端处理:
socket.on('notification', function(notifHTML){
$("#notificationsContainer").prepend(notifHTML);
$(".notifications-count").html('<i class="fas fa-dot-circle"></i>');
document.title = '(⚐) sweet';
});
然而,事实证明,每个连接到服务器的客户端都会收到该通知事件并以上述方式处理它;当我有三个浏览器连接到服务器时,它们都执行上面的代码;我可以在页面和新文档标题中看到结果。
我实际上可以通过将具有 .to 的行替换为以下内容来解决此问题:
io.of('/').in(userID.toString()).clients(async (error, clients) => {
for (var client of clients) {
io.sockets.connected[client].emit('notification', notifHTML);
}
})
然后,该事件仅发送给我希望它成为的客户端,即我展示的房间中的那个。 (如果一个用户从多个浏览器连接到服务器,这个房间可能包含多个客户端,所以我不能用针对单个套接字的代码替换这个房间代码。)但是,代码不需要这么冗长;我仍然想知道为什么 .to 没有按我期望的方式工作。据我阅读文档可知,它应该提供相同的功能,即仅向指定房间中的套接字发送事件。
【问题讨论】:
标签: javascript node.js websocket socket.io