6

我目前正在建立一个聊天只是为了好玩。我以前从未这样做过,而且我一般都尝试过EventSource API (Server-Sent Events)in JavaScript。大约 3 天前我才听说它,我觉得它很有趣,而且比设置WebSocket.

我知道长轮询会占用大量资源。但是,由于我从未听说过 EventSource,它对服务器有何影响?它是否使用相同数量的资源?

我注意到在 中Networks TabGoogle Chrome Developers ToolEventSource 确实创建了一个内容大小很大的请求(随着时间的推移)。有 1 个内容大小较大的请求会更好吗?

我的聊天目前正在运行两个 EventSource。一个用于聊天本身(运行 every 2500ms)和用于聊天的“正在输入..”机制(运行 every 250ms)。

在聊天大约一分钟后,两个请求的合并内容大小约为150kb. 不过,这将增加更多的消息。

我担心我的主人会暂停我的帐户。这就是我的一个使用轮询或长轮询的朋友发生的事情(我忘了)。我不确定 EventSource 使用的资源是否与轮询或长轮询一样多。

主要问题:EventSource 如何影响服务器?

  • 它如何使用资源?
  • 除了使用网络套接字之外还有什么更好的方法吗?
  • 有 1 个请求会创建大量内容还是有多个请求携带少量数据更好?
4

2 回答 2

4

长轮询比 EventSource 使用更多的资源,因为它不断地建立和破坏连接。使用 EventSource,只使用单个连接,客户端正在等待数据,而不是检查服务器是否有新数据。

使用长轮询时,客户端将在以下情况下断开连接:

  • 客户不想要更多数据
  • 客户端刚刚收到它的数据
  • 客户端等待数据超时

当服务器没有数据时,客户端会一直等到超时,直到服务器有数据。如果有数据,客户端断开连接并创建另一个连接。如果客户端超时,客户端将断开连接并建立另一个连接。因此,您可以从许多地方看到开销。

长轮询

  • 如果需要数据,客户端将建立新连接
  • 如果客户端超时,它会重新创建另一个连接
  • 如果客户端收到信息,它会重新创建一个连接

事件源

  • 客户端在与服务器连接时创建单个套接字
  • 当客户端接收到数据时,保持连接并重用
  • 由客户端使用带有标头的GET请求发起Accept: text/event-stream
  • 遵守同源限制

网络套接字

  • 客户端在与服务器连接时创建单个套接字
  • 当客户端或服务器接收到数据时,保持连接并重用
  • HTTP GET使用带有Upgrade: websocket标头的请求启动
  • 可以制作到任何来源(跨域)

资源消耗:

EventSource 的开销主要只是连接的存在。从这个意义上讲,它类似于 websockets,建立和维护单个连接。因此,由于持续的建立/销毁周期,您将使用长轮询获得最多的开销,来自 websockets 的第二大开销(因为它们是双向的),而来自单向的 EventSource 的开销最少。

更好的选择:

对于客户端和服务器之间的实时和双向通信,没有什么比 websocket 更好的了。这是客户端和服务器相互侦听数据而不是相互刺激数据的一种解决方案。

上证所要求

我认为您是在假设您认为 Chrome 中显示的内容是个人请求的情况下提出这个问题的。由于 EventSource 与服务器建立了一个套接字,因此您实际上是在读取通过 EventSource 套接字发送的累积数据量。因此,当您发送数据时,您正在重用相同的连接,您无需担心请求大小。


总之,大多数主机暂停轮询的原因是短轮询和长轮询都需要大量请求。如果您使用 EventSource 或 websockets,您使用的是使用套接字的实时通信,它不会向 HTTP 服务器“发送垃圾邮件”请求。(如果我发送了 100 个数据负载,EventSource 和 websockets 将使用相同的连接,长轮询将至少重新连接 100 次)您唯一需要注意的是服务器可以处理的最大并发连接数,因为套接字使用比轮询更少的 CPU 和资源。

需要考虑的有关 EventSource/SSE 的事项:

  • 使用传统的 HTTP 协议,websockets 不使用
  • 与 websockets 相比,浏览器支持较少,但对不支持的浏览器有 polyfills
  • 内置了对重新连接和事件的支持
  • 与 websocket 相比,协议更简单
于 2013-09-13T01:31:34.477 回答
1

要了解 SSE 对您的服务器的影响,您需要了解它们是如何工作的。我将首先解释一下长轮询,因为它是最接近的选择。

长轮询

使用长轮询,客户端向服务器发送请求,服务器保持它;如果它无话可说,它不会发送响应。对于您的聊天示例,您可以使用您收到的最新消息的 ID 发送请求,服务器将延迟发送响应,直到有新消息需要向您发送,此时响应被释放。

缺点是即使没有使用连接并且脚本正在运行(可能轮询数据库以获取新消息),连接也会保持活动状态。每次服务器向客户端发送内容时,您仍然需要一个新连接。

与常规轮询相比,优势在于流量大大减少,因为只有在有话要说时才会给出响应。

服务器发送事件

SSE 的工作方式与长轮询非常相似,因为它需要来自客户端的连接,并且只有在有话要说时才发送消息,但最大的区别是连接不会随着第一条消息关闭。显然,不必为每条消息建立新连接是一种胜利,不幸的是,服务器上的负面影响是相似的:连接保持活动状态,服务器脚本保持运行。优点是客户端只发送一个请求。

网络套接字

Web 套接字提供了真正的双向通信,但保持连接打开的原理是相同的。您可以从这里获得的优势是您可以按照您的意愿打包您的信息。

需要注意的一件事是,不同的服务器可以不同地处理这些情况。由于它专注于异步事件,无论您使用长轮询、SSE 还是 Web Sockets,NodeJS 似乎更适合作为聊天系统的服务器组件。

至于您的最后一个问题,这在很大程度上取决于您所处的情况以及“更好”的含义。如果更好的意思是更少的网络流量,那么大响应的开销应该比多个短响应少得多。

所以总结一下:

  • 就 CPU 而言,与长轮询或 Web 套接字相比不是很大的优势/劣势,但在网络使用方面比长轮询有一些优势
  • 如果您有时间处理额外的复杂性,网络套接字仍然是最好的
  • 可能1个请求会更好
于 2013-09-12T06:42:02.210 回答