io.to(),io.in()和socket.to()之间的差异,用于发送到房间中的所有客户端

时间:2017-03-23 22:37:14

标签: socket.io

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

除了上面链接的示例之外,文档中的任何其他位置都未列出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对象代表连接的客户端。如何使用传入的套接字对象广播到所有其他连接的套接字,如上例所示?

对以上内容的明确解释表示赞赏。

1 个答案:

答案 0 :(得分:2)

  

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

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

首先,socket.to()在名为_rooms的套接字上创建一个属性,该属性是一个房间名称数组。您可以在上下文here in the Github repository中查看整个代码,但这里是.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()的完整代码为here on 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);
}
  

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

每个套接字都包含对适配器的引用,并且适配器具有该适配器上所有套接字的列表。因此,可以将套接字形成适配器,连接到所有其他套接字。

我同意这是一个奇怪的功能重载,但这就是他们如何做到这一点。我猜他们想要让人们访问广播功能,当你所有人都提到的是一个单独的套接字时。

仅供参考,自己真正回答这些类型问题的唯一方法是查看代码,这无疑是使用开源库的巨大优势之一。我发现找到正确来源的最快方法是进入调试器中感兴趣的方法。启动调试器,在代码中设置断点,然后进入选择的功能,它将立即显示相关的源代码。如果你想看看它正在采取什么样的路径,你可以进一步逐步完成该功能。