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

Mad*_*bæk 780 html5 websocket server-sent-events

双方的WebSockets服务器发送的事件能够将数据推送到浏览器.对我来说,他们似乎是竞争技术.他们之间有什么区别?你何时会选择一个而不是另一个?

Ale*_*rey 919

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

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

SSE连接只能将数据推送到浏览器.在线股票报价或更新时间表或订阅源的twitters是可以从SSE中受益的应用程序的良好示例.

实际上,由于SSE可以完成的所有事情也可以通过Websockets完成,因此Websockets得到了更多的关注和喜爱,并且更多的浏览器支持Websockets而不是SSE.

但是,对于某些类型的应用程序来说,它可能过度,而后端可能更容易使用SSE等协议实现.

此外,SSE可以填充到旧版浏览器中,只使用JavaScript本身不支持它.可以在Modernizr github页面上找到SSE polyfill的一些实现.

陷阱:

  • SSE受到最大打开连接数的限制,打开各种标签时可能会特别痛苦,因为限制是按浏览器设置的,并设置为非常低的数字(6).该问题已在ChromeFirefox中标记为"无法修复"
  • 只有WS可以传输二进制数据和UTF-8,SSE仅限于UTF-8.(感谢Chado Nihi).

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

服务器发送事件与WebSockets

为什么要通过WebSockets选择Server-Sent Events?好问题.

SSE一直处于阴影中的一个原因是因为WebSockets等后来的API提供了更丰富的协议来执行双向全双工通信.拥有双向渠道对于游戏,消息应用程序以及需要双向近实时更新的情况更具吸引力.但是,在某些情况下,不需要从客户端发送数据.您只需要从某些服务器操作进行更新.一些示例将是朋友的状态更新,股票行情,新闻源或其他自动数据推送机制(例如,更新客户端Web SQL数据库或IndexedDB对象存储).如果您需要将数据发送到服务器,XMLHttpRequest始终是朋友.

SSE通过传统HTTP发送.这意味着他们不需要特殊的协议或服务器实现来实现工作.另一方面,WebSockets需要全双工连接和新的Web Socket服务器来处理协议.此外,Server-Sent Events具有WebSockets设计缺乏的各种功能,例如自动重新连接,事件ID以及发送任意事件的能力.


TLDR摘要:

SSE优于Websockets的优点:

  • 通过简单的HTTP而不是自定义协议传输
  • 可以使用javascript进行填充,以便将SSE"backport"到尚不支持它的浏览器.
  • 内置支持重新连接和事件ID
  • 更简单的协议

Websockets优于SSE的优点:

  • 实时,双向通信.
  • 更多浏览器的原生支持

SSE的理想用例:

  • 股票报价流
  • twitter Feed更新
  • 浏览器通知

SSE陷阱:

  • 没有二进制支持
  • 最大开放连接限制

  • 聊天完全可以与SSE一起使用 - 您可以使用常规POST将消息发送到服务器.只有在您实施Google Wave聊天时才需要WebSockets. (121认同)
  • 确实可以使用SSE完成聊天和其他实时应用程序.但是,这需要POSTing回复"带外",即,这不受SSE协议的控制,并且对于SSE和Websockets之间的差异的基本解释似乎不是一个很好的例子.您可以实现与基本HTTP的聊天,每秒轮询服务器并发布新的回复.这并不意味着它是最好/最优雅的方式. (119认同)
  • 我认为pomeL的解决方案对于大多数情况来说都是一个很好的折衷方案,因为JS总是能够通过AJAX POST"推送"到服务器.根据我的经验,主要问题通常是JS需要轮询新信息,但SSE负责这一点.:d (13认同)
  • @MattDiPasquale Wave在您键入时会单独发送每个键,而不是立即发送完整的消息.对于1次击键,200字节的POST开销将是浪费的,而WebSocket的大约为6. (12认同)
  • 说它们不是竞争技术似乎有点奇怪,然后继续描述它们都可以用来实现类似的解决方案.我会说这让他们竞争. (6认同)
  • 如果服务器使用 HTTP/2,则所有请求(包括 SSE)都可以多路复用到一个 TCP 连接中,与使用需要专用 TCP 连接的 WebSocket 相比,这可以节省资源。 (4认同)
  • 该限制是针对每个域的,而不是针对每个浏览器的。我最多可以有 6 个 sse 访问 www.example.com,其他 6 个 sse 访问 www.example2.com (3认同)
  • 或许需要明确指出:SSE和WS都支持UTF-8编码的数据,但WS也可以传输_binary_数据。 (2认同)
  • 根据[这篇博客](https://streamdata.io/blog/push-sse-vs-websockets/),服务器在发送消息之前不可能检测SSE是否还活着。 (2认同)

Dre*_*kes 106

根据caniuse.com:

您可以使用仅客户端的polyfill将SSE的支持扩展到许多其他浏览器.使用WebSockets的可能性较小.一些EventSource polyfill:

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

了解更多关于SSE的信息:

了解有关WebSockets的更多信息:

其他差异:

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

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

at5*_*321 42

到了2023年,情况已不再像以前那样了。

几年前,当 IE 仍然拥有相当大的市场份额时,SSE的一个缺点是 IE 完全缺乏本机支持(而IE 10+ 支持WebSockets )。如今,根据caniuse.com 的数据,这两种技术在客户端的支持率几乎相同:WebSockets 的支持率为 98.35%,而SSE 的支持率为 98.03%(这些统计数据适用于全球用户)。

从历史上看,SSE 的一个严重限制,即每个域 6 个连接限制(yourapp.com在许多浏览器选项卡中打开时出现的问题)对于HTTP/2. 所有现代浏览器都支持HTTP/2(全球用户的97.16%),并且在服务器端HTTP/2+也超越了HTTP/1过去几年。

在 SSE 和 WebSocket 之间进行选择时需要考虑多种因素:

  • SSE 通常更容易实现并且更容易测试/调试(curl可以使用简单的)。
  • WebSocket 支持双向(全双工)通信。也就是说,如果需要双向通信,SSE可以与 AJAX 结合使用。在这些情况下,WebSocket 通常被认为是更简单的选择,但我认为这种概括可能会产生误导,因为它很大程度上取决于应用程序的类型、设计方式和使用的技术。
  • SSE 仅支持 UTF-8 文本消息,而 WebSocket 还可以传输二进制数据。
  • 我们可以通过内置的EventSource API在客户端使用 SSE 。然而,现在人们经常选择使用一个库,例如流行的fetch-event-source,它是 EventSource 的 SSE 兼容替代品,它提供了附加功能,例如自定义标头、更高级的重试策略、在以下情况下自动关闭连接浏览器最小化等
  • 从实际的角度来看,我还建议研究您的应用程序服务器对每种技术的支持程度。请注意,有些依赖于附加模块和/或库。您可能想查看一些示例,并可能构建一个快速的 PoC。


Yaf*_*fle 15

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


Zim*_*Zim 9

它们在语义上是不同的。

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

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

当然你可以自己在websocket上实现一层“pub-sub模式”或“req-res模式”。


小智 7


Websocket VS SSE


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

Example - Online chat application.
Run Code Online (Sandbox Code Playgroud)

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

Example - Online stock quotes or cricket score website.
Run Code Online (Sandbox Code Playgroud)

  • 在浏览器端,Websocket 被烘焙到浏览器中,因此浏览器端不需要外部库 (3认同)

Dre*_*eur 6

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

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

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

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

  • 我在服务器发送事件中看到的一个问题是,某些代理/防火墙可能会阻止它,因为它没有 Content-Length 标头 (2认同)