为啥以及如何 SSE(服务器发送事件)是单向的

Posted

技术标签:

【中文标题】为啥以及如何 SSE(服务器发送事件)是单向的【英文标题】:Why and how SSE (Server-Sent Events) are unidirectional为什么以及如何 SSE(服务器发送事件)是单向的 【发布时间】:2018-09-20 10:54:05 【问题描述】:

https://developer.mozilla.org/en-US/docs/Web/API/EventSource

EventSource 接口是 Web 内容与服务器发送事件的接口。 EventSource 实例打开与 HTTP 服务器的持久连接,该服务器以文本/事件流格式发送事件。连接保持打开状态,直到通过调用 EventSource.close() 关闭。

据我了解,服务器发送的事件需要persistent HTTP connection (Connection: keep-alive),因此类似于在使用 Web 套接字时保持连接有效。

如果连接是持久的,为什么服务器发送的事件是单向的? Web 套接字连接也是持久的。

在这种情况下,如果我向我的 HTTP 服务发送请求并且由于EventSource 而打开了持久连接,会发生什么情况。它会重新使用EventSource打开的HTTP连接还是打开一个新的连接?

如果它重复使用EventSource打开的连接,它如何被认为是单向的?

可能是微不足道的,但我不得不问,因为它不清楚。因为没有提及当EventSource 打开现有连接时后续 HTTP 请求会发生什么。

例如,在我看来,使用 SSE 实现集中式聊天应用程序是可能的:

用户 1 向用户 2 发送消息(通过将其发送到 HTTP 服务器)。服务器向用户 2 发送新消息,用户 2 向 HTTP 服务器发送另一个请求,用户 1 的消息,服务器向用户 1 发送事件。

怎么不认为是双向的?

相关:

What's the behavioral difference between HTTP Stay-Alive and Websockets?

【问题讨论】:

【参考方案1】:

SSE 是单向的,因为当您打开 SSE 连接时,只有服务器可以向客户端(浏览器等)发送数据。客户端无法发送任何数据。 SSE 比 WebSockets 有点老,因此可能是这两种技术之间单向和双向支持之间的区别。

在您的用例中,如果您打开 SSE 连接(即 HTTP 连接),则只有服务器能够发送数据。如果您希望向您的 HTTP 服务发送请求,则需要打开一个新的“经典”HTTP 连接。您将看到您的浏览器打开了两个 HTTP 连接:1 个用于 SSE 连接,1 个用于传统 HTTP 请求(短期)。

您可以与 SSE 进行聊天。你可以有一个 SSE 连接(因此是 HTTP)来让用户从服务器接收消息。您可以使用 POST HTTP 请求来使用户能够发送他/她的消息。

请注意,大多数浏览器可以打开大约 6 个到同一主机的 HTTP/1.x 连接。因此,如果您使用 1 个 SSE 连接,则可能会保留 5 个 HTTP/1.x 连接。这仅适用于 HTTP/1.x。使用 HTTP 2.x,到同一主机的连接是多路复用的:因此,理论上,您可以同时发送任意数量的 HTTP 请求,或者您可以打开任意数量的 SSE 连接,从而突破 6 个连接的限制。

您可以观看这篇文章 (https://streamdata.io/blog/push-sse-vs-websockets/) 和这段视频 (https://www.youtube.com/watch?v=NDDp7BiSad4),以深入了解这项技术以及它是否能满足您的需求。他们总结了 SSE 和 WebSocket 的优缺点。

【讨论】:

很好的答案!所以我认为使用 SSE 可能比 Web 套接字更昂贵,因为无论如何都会打开新连接,Web 套接字只保留 1 个连接进行通信。 你是对的。但是对于 HTTP/2,情况就不同了。从我见过的用例来看,您通常只需要在服务器和客户端之间建立一个 SSE 连接。但再一次,这取决于您的用例和您的要求:)

以上是关于为啥以及如何 SSE(服务器发送事件)是单向的的主要内容,如果未能解决你的问题,请参考以下文章

服务器端事件发送SSE

Javascript Ajax总结——其他跨域技术之服务器发送事件SSE

服务器发送事件 Golang

ServiceStack:通过 WebSocket 选择服务器发送的事件

Spring boot SSE(服务器发送事件):如何动态发送响应

How Javascript works (Javascript工作原理) 深入理解 WebSockets 和带有 SSE 机制的HTTP/2 以及正确的使用姿势