ChatGPT解决这个技术问题 Extra ChatGPT

WebSockets 与服务器发送的事件/事件源

WebSocketsServer-Sent Events 都能够将数据推送到浏览器。对我来说,它们似乎是相互竞争的技术。它们之间有什么区别?你什么时候会选择一个而不是另一个?

不知道你如何看待他们的竞争。一个是同步的,可以/将用于近乎实时的数据传输,而另一个是异步的,将用于完全不同的目的(有效地从服务器端应用程序发送类似 toast 的消息)。
我真正喜欢 SSE 的一件事是它很容易排除故障……只需使用 curl 打开对您的 SSE 服务器的请求。由于它只是 HTTP 上的文本格式,因此很容易看到发生了什么。
@BrianDriscoll - 异步/同步 - 哪个是哪个?据我所知,两者都启用异步传输?
SSE 不适用于 IE,websockets 可以
@cellepo 请参阅 SSE 上的 MDN 页面。它列出了几个 polyfill。 Remy Sharp 有 186 行,您可以将其精简到基本部分,但是是的,50 行略低于... ;)

A
Alex Recarey

Websockets 和 SSE(服务器发送事件)都能够将数据推送到浏览器,但它们不是竞争技术。

Websockets 连接既可以向浏览器发送数据,也可以从浏览器接收数据。可以使用 websocket 的应用程序的一个很好的例子是聊天应用程序。

SSE 连接只能将数据推送到浏览器。在线股票报价或更新时间线或提要的 Twitter 是可以从 SSE 中受益的应用程序的很好示例。

在实践中,由于 SSE 可以完成的所有事情也可以通过 Websockets 完成,因此 Websockets 得到了更多的关注和喜爱,并且比 SSE 更多的浏览器支持 Websockets。

但是,对于某些类型的应用程序来说,这可能是多余的,并且后端可以更容易地使用诸如 SSE 之类的协议来实现。

此外,SSE 可以被填充到仅使用 JavaScript 本身不支持它的旧浏览器中。可以在 Modernizr github page 上找到 SSE polyfill 的一些实现。

陷阱:

SSE 受到最大打开连接数的限制,当打开各种选项卡时可能会特别痛苦,因为限制是每个浏览器的并且设置为非常低的数字 (6)。该问题已在 Chrome 和 Firefox 中标记为“无法修复”。此限制针对每个浏览器 + 域,因此这意味着您可以在所有选项卡上打开 6 个 SSE 连接到 www.example1.com 和另外 6 个 SSE 连接到 www.example2.com(感谢 Phate)。

只有 WS 可以同时传输二进制数据和 UTF-8,SSE 仅限于 UTF-8。 (感谢查多尼希)。

一些具有数据包检测功能的企业防火墙无法处理 WebSocket(Sophos XG Firewall、WatchGuard、McAfee Web Gateway)。

HTML5Rocks 有一些关于 SSE 的好信息。从该页面:

服务器发送事件与 WebSockets 为什么选择服务器发送事件而不是 WebSockets?好问题。 SSE 一直被隐藏起来的一个原因是因为后来的 API(如 WebSockets)提供了更丰富的协议来执行双向、全双工通信。对于游戏、消息传递应用程序以及需要双向近乎实时更新的情况,拥有双向通道更具吸引力。但是,在某些情况下,不需要从客户端发送数据。您只需要一些服务器操作的更新。一些例子是朋友的状态更新、股票行情、新闻提要或其他自动数据推送机制(例如更新客户端 Web SQL 数据库或 IndexedDB 对象存储)。如果您需要向服务器发送数据,XMLHttpRequest 始终是您的朋友。 SSE 通过传统的 HTTP 发送。这意味着它们不需要特殊的协议或服务器实现即可工作。另一方面,WebSockets 需要全双工连接和新的 Web Socket 服务器来处理协议。此外,Server-Sent Events 具有 WebSockets 在设计上缺乏的各种功能,例如自动重新连接、事件 ID 和发送任意事件的能力。

TLDR 总结:

SSE 相对于 Websockets 的优势:

通过简单的 HTTP 而不是自定义协议传输

可以用 javascript 填充以将 SSE“反向移植”到尚不支持它的浏览器。

内置支持重新连接和事件 ID

更简单的协议

企业防火墙进行数据包检查没有问题

Websockets 相对于 SSE 的优势:

实时,双向通信。

更多浏览器的原生支持

SSE 的理想用例:

股票行情流

推特提要更新

浏览器通知

上证所陷阱:

不支持二进制

最大打开连接数限制


使用 SSE 聊天是完全可行的——您可以使用常规 POST 向服务器发送消息。仅当您正在实施聊天 a'la Google Wave 时才需要 WebSockets。
确实可以使用 SSE 完成聊天和其他实时应用程序。但是,这需要“带外”发布回复,即,这不受 SSE 协议控制,并且似乎不是基本解释 SSE 和 Websockets 之间差异的好例子。您可以使用基本的 HTTP 每秒轮询服务器并发布新回复来实现聊天。这并不意味着它是最好/最优雅的方式。
我认为 pomeL 的解决方案在大多数情况下是一个很好的折衷方案,因为 JS 总是可以通过 AJAX POST 将内容“推送”到服务器。根据我的经验,主要问题通常是 JS 需要轮询新信息,但 SSE 会处理这个问题。 :D
@MattDiPasquale Wave 在您键入时单独发送每个键,而不是一次发送完整的消息。与 WebSocket 大约 6 个字节相比,1 次击键 200 字节的 POST 开销是浪费的。
说它们不是竞争技术似乎有点奇怪,然后继续描述它们都可以用来实现类似的解决方案。我会说这让他们竞争。
G
Gras Double

根据 caniuse.com:

98.33% 的全球用户原生支持 WebSockets

97.67% 的全球用户原生支持服务器发送事件

您可以使用仅限客户端的 polyfill 将 SSE 支持扩展到许多其他浏览器。 WebSockets 不太可能发生这种情况。一些 EventSource polyfills:

Remy Sharp 的 EventSource,没有其他库依赖项 (IE7+)

Rick Waldron 的 jQuery.EventSource

Yaffle 的 EventSource(替换本机实现,跨浏览器规范化行为)

如果您需要支持所有浏览器,请考虑使用像 web-socket-jsSignalRsocket.io 这样的库,它们支持多种传输方式,例如 WebSockets、SSE、Forever Frame 和 AJAX 长轮询。这些通常也需要对服务器端进行修改。

从以下位置了解有关 SSE 的更多信息:

HTML5 摇滚文章

W3C 规范(已发布版本,编辑草稿)

从以下位置了解有关 WebSocket 的更多信息:

HTML5 摇滚文章

W3C 规范(已发布版本,编辑草稿)

其他区别:

WebSockets 支持任意二进制数据,SSE 只使用 UTF-8


我想在 2016 年指出 > 95% 的全球用户原生支持 WebSockets。所有浏览器和设备都支持 WebSocket 超过 4 年。如果不支持,Socket.IO 将回退到 AJAX 长轮询并为您处理模拟 WebSockets 的复杂性,这使得支持 100%。如果您在 2016 年使用的不是 WebSockets,那么您使用的是过时的技术。
@NickSteele 那是胡说八道的炒作声明。如果它们符合您的用例并且并不意味着任何东西都过时了,那么依赖旧标准是完全可以的。这只是一个不同的标准。例如:XHR 仍然可以做很多 Fetch API 做不到的事情,所以它并没有过时。这不一样。我过去使用过 WS,但从经验中知道,当它不理解 WS 时,可以以噪声企业防火墙的形式遇到障碍,阻止请求。 SSE 的工作效率非常高,易于理解和实施,并且易于调试。对于我们的单向数据流,它是完美的。
然后用夸张的方式替换 BS :-) WS 不能替代 XHR/HTTP,就像无人机不能替代送货车一样。这是不同的用例。 WS 不是 HTTP 并且有不同的甜蜜点。如果您尝试,您最终会在用户空间中重新实现 HTTP(很差)。此外,您暗示的事情没有给出事实:WS 只是一个支持服务器推送的双向协议。我从未见过任何设计文档提到它被开发为任何东西的替代品。资源?年龄本身并不是一个因素。如果可以选择,请选择最简单的实现来检查您的所有要求。
就在两年前(2017 年),我正在调试 Node JS 进程的堆转储,其中 Socket.io 代码导致 IIS 进程中出现大量内存碎片,最终直接与 Azure 的 Node 团队交谈。总的复杂性不是免费的。如果您可以使用一个简单的 20 行脚本作为您对服务器的依赖,同时仍然能够为 100K 客户端提供服务,那么我会选择它。不过,我喜欢 WS 的功能,但在选择解决方案之前先看看你需要什么。
同时(2021 年):WebSockets 97%,SSE 96%。
Y
Yaffle

Opera, Chrome, Safari 支持 SSE, Chrome, Safari 在 SharedWorker 内部支持 SSE Firefox 支持 XMLHttpRequest readyState 交互,所以我们可以为 Firefox 制作 EventSource polyfil


G
Gaurav Tiwari

Websocket VS SSE

Web Sockets - 它是一种通过单个 TCP 连接提供全双工通信通道的协议。例如服务器和浏览器之间的双向通信 由于协议比较复杂,服务器和浏览器必须依赖 websocket 库,即 socket.io

Example - Online chat application.

SSE(Server-Sent Event) - 在服务器发送事件的情况下,仅从服务器到浏览器进行通信,浏览器不能向服务器发送任何数据。这种通信主要用于只需要显示更新的数据时,然后服务器在数据更新时发送消息。例如服务器到浏览器之间的单向通信。这个协议不太复杂,所以不需要依赖外部库JAVASCRIPT本身提供的EventSource接口来接收服务器发送的消息。

Example - Online stock quotes or cricket score website.

在浏览器端,websockets 被烘焙到浏览器中,因此浏览器端不需要外部库
D
Drew LeSueur

需要注意的一件事:我遇到了 websockets 和公司防火墙的问题。 (使用 HTTPS 会有所帮助,但并非总是如此。)

请参阅https://github.com/LearnBoost/socket.io/wiki/Socket.IO-and-firewall-software https://github.com/sockjs/sockjs-client/issues/94

我认为服务器发送事件没有那么多问题。但我不知道。

也就是说,WebSocket 非常有趣。我有一个使用 websockets 的小网络游戏(通过 Socket.IO)(http://minibman.com


我也遇到了公司防火墙的问题。
我在服务器发送事件中看到的一个问题是某些代理/防火墙可能会阻止它,因为它没有 Content-Length 标头
如果 X-Accel-Buffering 标头未设置为 no,Nginx 也可以阻止它
Z
Zim

它们在语义上是不同的。

websocket 具有“双向数据流”的原生语义含义。

而 sse 具有“发布-订阅模式”或“请求-响应模式,尽管响应是流”的本机语义含义。

当然,您可以自己在 websocket 上实现一层“pub-sub 模式”或“req-res 模式”。但这效率较低。