io.to)、io.in() 和 socket.to() 之间向房间中的所有客户端发出的区别



Socket.io 文档似乎指定了几种向房间中所有连接的客户端发出事件的方法。它们如下:

  • io.to(),如此处的第一个示例所示:https://socket.io/docs/server-api/#socket-join-room-callback
  • io.in(),如在发射备忘单中找到的,在这里找到:https://socket.io/docs/emit-cheatsheet/
  • socket.to(),如这里找到的:https://socket.io/docs/server-api/#socket-to-room

除了上面链接的示例外,io.to()io.in()都没有在文档中的其他任何地方列出。这些方法究竟有什么作用,在哪里可以找到有关它们的更多信息?

socket.to()可以在io.on('connection', callback)事件中使用,如下所示:

io.on('connection', function(socket){
// to one room
socket.to('others').emit('an event', { some: 'data' });
// to multiple rooms
socket.to('room1').to('room2').emit('hello');
});

但是,这没有意义,因为传递到此回调中的socket对象表示连接的客户端。如何使用传入套接字对象广播到所有其他连接的套接字,如上例所示?

感谢对上述内容的明确解释。

但是,这没有意义,因为传递到此回调的套接字对象表示连接的客户端。

如果在调试器中跟踪这些调用,则可以看到发生了什么。

首先,socket.to()在套接字上创建一个名为_rooms的属性,该属性是房间名称的数组。 您可以在 Github 存储库的上下文中看到整个代码,但这里是.to()的相关部分:

Socket.prototype.to =
Socket.prototype.in = function(name){
if (!~this._rooms.indexOf(name)) this._rooms.push(name);
return this;
};

每次连续调用.to()只是数组的一个附加空间。

然后,socket.emit()检查_rooms属性是否存在,如果存在,它会调用this.adapter.broadcast(...)来获取适配器并告诉它将此消息广播到该适配器上除当前适配器之外的所有套接字。socket.emit()的完整代码在Github上。 代码的特定广播部分是这样的:

if (this._rooms.length || this.flags.broadcast) {
this.adapter.broadcast(packet, {
except: [this.id],
rooms: this._rooms,
flags: this.flags
});
} else {
// dispatch packet
this.packet(packet, this.flags);
}

如何使用传入套接字对象广播到所有其他连接的套接字,如上例所示?

每个套接字都包含对适配器的引用,适配器具有该适配器上所有套接字的列表。 因此,可以从插座到适配器,到所有其他插座。

我同意这有点奇怪的功能过载,但这就是他们的做法。 我猜他们想让人们访问广播功能,而你引用的只是一个单独的套接字。


仅供参考,真正回答这些未记录在案的此类问题的唯一方法是查看代码,这无疑是使用开源库的巨大优势之一。 我发现访问正确源的最快方法是单步执行调试器中感兴趣的方法。 启动调试器,在代码中设置断点,然后单步执行所选函数,它将立即显示相关的源代码。 然后,如果您想查看该函数所采用的路径,可以进一步单步执行该函数。

对于像我这样遇到这个问题的人,这里是文档的链接以进行解释: https://socket.io/docs/v3/rooms/index.html

最新更新