如何使用循环连接socket.io客户端

时间:2018-08-13 04:27:37

标签: javascript reactjs sockets websocket socket.io

我有许多在迭代端口(端口4001、4002、4003等)上服务的socket.io服务器

我想使用循环将每个套接字客户端连接到相应的服务器:

connectSockets = (sensors) => {
  const responses = {};

  for (const [idx, sensor] of sensors.entries()) {
    const socket = socketIOClient(`${endpointBase}:${port + idx}`);

    socket.on(`From::${sensor}`, data => {
      responses[sensor] = data
    });
  }

  this.setState({
    responses
  });
};

当我在循环中中断时:

responses[sensor] = data

我可以看到数据。甚至将其分配给适当的“响应”属性。

但是,当我跳出循环并闯入setState时,我会看到:

responses = {}

不知道为什么。某种范围的问题?或者也许我对socket.io的工作方式感到困惑-第一次使用它。有趣的是,当我中断“ const socket”时,我得到了预期的三个迭代,但是当我中断了“ respons [sensor] = data”时,我得到了不止3次迭代。有人有什么想法吗?

3 个答案:

答案 0 :(得分:2)

好吧,我自己弄清楚了。事实证明,这对socket.io的工作方式有误解。正如t.niese提到的,回调是异步的。

我需要做的是在套接字连接中设置状态,因为在循环完成时“数据”不一定可用:

  socket.on(`From::${sensor}`, data => {
    responses[sensor] = data
    this.setState({responses});
  });

工作完美。

答案 1 :(得分:0)

它不是您在问题(或答案)中所假设的范围界定问题,而是与何时执行部分代码有关。如果您放置一些console.log(或代码中的断点),它将变得显而易见:

connectSockets = (sensors) => {
  const responses = {};

  console.log('before loop')
  for (const [idx, sensor] of sensors.entries()) {
    const socket = socketIOClient(`${endpointBase}:${port + idx}`);

    socket.on(`From::${sensor}`, data => {
      console.log(`socket.on callback for: ${sensor}`)
      responses[sensor] = data
    });
  }
  console.log('after loop')

  this.setState({responses});
};

控制台中的输出或达到这些断点的顺序为:

before loop
after loop
socket.on callback for: ...
...
socket.on callback for: ...

.on中注册的事件处理程序在发生偶数时被调用,但是由于JavaScript不是多线程的,因此在向{{1 }}。

您可以通过将.on移至事件回调来解决此问题(如您所知)。现在您可以多次调用this.setState({responses})。如果出现问题,请取决于您的this.setState函数。

答案 2 :(得分:0)

responses[sensor] = data在随后的时间指针上异步触发。 this.setState({responses})在同一事件循环中被调用。这就是为什么您找不到填充任何东西的原因。