【问题标题】:Calling emit in js在js中调用emit
【发布时间】:2018-03-17 15:36:08
【问题描述】:

我一直在试图回答如果 emit 没有任何注册的侦听器会发生什么。

如果客户端在没有任何监听器的情况下通过发射发送垃圾邮件会导致漏洞吗?

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

【问题讨论】:

  • 不,这可能很容易......

标签: javascript node.js socket.io eventemitter


【解决方案1】:

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

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

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

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

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


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

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

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

【讨论】:

  • socket-anti-spam 包中使用了一种"leacky bucket algorithm",用于计算可用的spamScore 值。当此值超过某个阈值时,库将应用 2 级规则。它将拒绝尝试重新连接的客户端断开连接。它还会在这段时间内自动倒计时。但不幸的是,它仅适用于具有注册侦听器的事件。它不会为未连接侦听器的事件添加 spamScore。但检查此事件也需要执行时间和 CPU。
  • @MaxBender - 是的,速率限制需要少量 CPU 来进行计数。没有办法避免这种情况。您要么想要/需要速率限制,要么不想要。您还可以使用 Nginx 等代理并在该级别进行速率限制。
猜你喜欢
  • 2020-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-24
  • 1970-01-01
  • 2021-06-19
  • 2013-12-21
  • 1970-01-01
相关资源
最近更新 更多