在 js 中调用 emit

Calling emit in js

我无法回答如果 emit 没有任何已注册的侦听器会发生什么。

如果客户端在没有任何侦听器的情况下发送垃圾邮件,是否会导致漏洞?

while(true){
    socket.emit('not_registered_event_string');
}

如果您 .emit() 没有任何听众,这不会造成任何问题。 EventEmitter 对象只会检查您传入的消息名称以获取侦听器列表,并会找到 none,因此什么都不做。

但是,服务器中的这个循环:

while(true){
    socket.emit('not_registered_event_string');
}

是一个无限循环,会阻止您的 node.js 进程执行任何其他操作。它将永远停留在该循环中,并且将无法处理任何其他事件或做任何其他事情。

这是因为 node.js 在单个线程中运行您的 Javascript 所以只要该单个线程在上面的 while 循环中循环,它就无法处理任何其他消息或做任何其他事情。 node.js 是一个事件驱动的环境。您收到一个事件,处理该事件,您 return 将控制权交还给系统,然后系统可以处理下一个事件。如果您永远循环,则不会处理任何事件,并且您的 node.js 进程将显示为挂起(即使您的循环可能仍然是 运行)。


客户端中的相同循环只会向您的服务器发送大量消息。服务器可能可以很好地处理它们,因为如果没有侦听器,则在接收到它们时基本上无事可做。但是,它会从您的服务器中抢夺带宽和 CPU 来处理空消息。

如果您想保护您的服务器免受客户端垃圾邮件事件的影响,您可以 "rate limit" 一个客户端,如果它超过每秒或每分钟消息的特定速率,您可以直接断开其连接。速率限制是一个经过深入研究的主题,许多文章都写过,并且有许多方案带有 node.js 的预构建包以帮助实施速率限制。我读过的一个常见的是 "leaky bucket" algorithm.

速率限制是服务器保护自己免受恶意客户端攻击的常用方法。如果继续滥用,您甚至可能会暂停或撤销帐户对您网站的访问权限,这样该帐户甚至无法登录您的网站。像 Google 这样的人对他们的大部分(也许是全部)服务使用速率限制来保护他们免受意外或有目的的过载攻击。