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 的单独文件中监听事件