Node JS、Socket.io、异步和阻塞事件循环

Posted

技术标签:

【中文标题】Node JS、Socket.io、异步和阻塞事件循环【英文标题】:Node JS, Socket.io, Async, and blocking Event Loop 【发布时间】:2019-01-12 15:02:13 【问题描述】:

我正在使用 Caolan 的 Node JS、Socket.io 和 Async 模块开发一个应用程序。

我想问一些关于向大量客户端发出的问题,以及它是否会阻塞事件循环。

为了在我的应用程序中使用,我需要堆叠套接字(连接的客户端信息),并管理我需要发送给谁。

因此,一旦我知道我需要向谁发送数据,我就会使用 Async.each 循环访问客户端以向客户端发送数据。

例子:

    async.each(clientsIds,
      function(item,cb)
      
        clients[item].emit('sendData', datas);
    cb();
      ,
      function(err)
      

      
    );  

所以我的问题是:如果我连接了 1000000 个客户端,当我发送数据时它会阻塞事件循环直到它完成向所有客户端发出吗?

我单独连接,并尝试向自己发出 1000000 次时,它会阻塞事件循环,直到函数完成运行。是因为我将它发送 1000000 给相同的客户端,还是如果它是 1000000 个不同的连接客户端,结果会相同?

如果有人可以帮助我,请提前感谢!我无法对大量连接的客户进行测试以自己确认。

(对不起,如果这是一个菜鸟问题,我不是专业人士)

【问题讨论】:

【参考方案1】:

直接依赖于emit函数,是同步还是异步?

异步库不会阻塞你的事件循环,它通过回调处理事情, 现在所有 1000000 回调都在队列中等待调用,现在每当事件循环将函数一一取出到调用堆栈,emit 函数完成所有任务(一些繁重的操作)在同一个线程或唯一的事件循环中,那么这会使其他 999999 回调等待,但是如果 .emit 函数将任务卸载到不同的运行器,例如 db 调用,让我们说 mongodb,节点 js 驱动程序将执行 io 的任务卸载到mongodb 服务器,并在不阻塞事件循环的情况下继续运行。基本上检查发射在做什么。如果它不会做很多事情,那么它肯定不会阻塞你唯一的事件循环。

【讨论】:

感谢您的回复。好吧,根据这个:***.com/questions/33160697/…socket.io EMIT 函数应该是异步的,但是无论我做什么测试(我的 app.js 中有一个 setInterval 每 500 毫秒做一次工作,所以我可以查看事件循环是否在某些时候被阻塞点与否),当我向 1000000 个客户端发出(在我的测试中它们都是同一个客户端的副本:我与应用程序的连接)时,它会阻塞事件循环 11 秒,直到它完成发射。我不知所措:(。不过再次感谢。

以上是关于Node JS、Socket.io、异步和阻塞事件循环的主要内容,如果未能解决你的问题,请参考以下文章

STOMP 上的重复事件 Socket.io 和 Node.js

Node.js+Socket.io+MongoDB webapps 是如何真正异步的?

如何在 node.js 中接收 socket.io 客户端事件?

Socket.io - 在 node.js 的单独文件中监听事件

Node.js - 如何从 app.js 外部发出 socket.io 事件?

如果使用 Node.js 在 Socket.io 中的应用程序中登录功能,则为特定用户发出事件