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


当前回答

它们在语义上有所不同。

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

sse的原生语义是“发布-订阅模式”或“请求-响应模式,尽管响应是一个流”。

当然,你可以自己在websocket上实现一层“发布-订阅模式”或“需求模式”。

其他回答

它们在语义上有所不同。

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

sse的原生语义是“发布-订阅模式”或“请求-响应模式,尽管响应是一个流”。

当然,你可以自己在websocket上实现一层“发布-订阅模式”或“需求模式”。

2023年的情况与过去大不相同。

几年前,当IE仍然拥有相当大的市场份额时,SSE的一个缺点是完全缺乏IE的本地支持(而WebSockets由IE 10+支持)。现在,根据caniuse.com的数据,这两种技术在客户端的支持几乎是一样的:WebSockets的98.35% vs SSE的98.03%(这些数据是针对全球用户的)。

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

在SSE和WebSockets之间选择时需要考虑以下几点:

SSE is generally simpler to implement and easier to test/debug (a simple curl could be used). WebSockets support bidirectional (full-duplex) communication. That said, SSE could be used in conjunction with AJAX if bidirectional communication is needed. WebSockets are often said to be the simpler option in those cases, but I think such generalizations can be misleading, as it largely depends on the type of application, how it's designed and the technologies used. SSE supports UTF-8 text messages only, whereas WebSockets can also transmit binary data. From a practical standpoint, I'd also recommend to research how well your application server supports each of those technologies. Note that some rely on additional modules and/or libraries. You might want to look at some examples and maybe build a quick PoC.

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

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

SSE连接只能向浏览器推送数据。在线股票报价或twitter更新时间轴或提要是可以从SSE获益的应用程序的好例子。

实际上,因为所有可以用SSE完成的事情都可以用Websockets完成,所以Websockets得到了更多的关注和喜爱,而且比SSE支持Websockets的浏览器也更多。

然而,对于某些类型的应用程序来说,它可能太过了,并且使用SSE之类的协议可以更容易地实现后端。

此外,SSE可以被填充到仅使用JavaScript原生不支持它的旧浏览器中。SSE腻子的一些实现可以在Modernizr github页面上找到。

陷阱:

SSE suffers from a limitation to the maximum number of open connections, which can be specially painful when opening various tabs as the limit is per browser and set to a very low number (6). The issue has been marked as "Won't fix" in Chrome and Firefox. This limit is per browser + domain, so that means that you can open 6 SSE connections across all of the tabs to www.example1.com and another 6 SSE connections to www.example2.com (thanks Phate). Only WS can transmit both binary data and UTF-8, SSE is limited to UTF-8. (Thanks to Chado Nihi). Some enterprise firewalls with packet inspection have trouble dealing with WebSockets (Sophos XG Firewall, WatchGuard, McAfee Web Gateway).

HTML5Rocks有一些关于SSE的好信息。从那一页开始:

Server-Sent Events vs. WebSockets Why would you choose Server-Sent Events over WebSockets? Good question. One reason SSEs have been kept in the shadow is because later APIs like WebSockets provide a richer protocol to perform bi-directional, full-duplex communication. Having a two-way channel is more attractive for things like games, messaging apps, and for cases where you need near real-time updates in both directions. However, in some scenarios data doesn't need to be sent from the client. You simply need updates from some server action. A few examples would be friends' status updates, stock tickers, news feeds, or other automated data push mechanisms (e.g. updating a client-side Web SQL Database or IndexedDB object store). If you'll need to send data to a server, XMLHttpRequest is always a friend. SSEs are sent over traditional HTTP. That means they do not require a special protocol or server implementation to get working. WebSockets on the other hand, require full-duplex connections and new Web Socket servers to handle the protocol. In addition, Server-Sent Events have a variety of features that WebSockets lack by design such as automatic reconnection, event IDs, and the ability to send arbitrary events.


TLDR简介:

SSE相对于Websockets的优点:

通过简单的HTTP传输,而不是自定义协议 可以用javascript“反向移植”SSE到还不支持它的浏览器。 内置对重新连接和事件id的支持 简单的协议 企业防火墙做包检查没有问题

Websockets相对于SSE的优点:

实时,双向交流。 更多浏览器的本地支持

SSE的理想用例:

股票行情流 推特更新 浏览器通知

如果gotchas:

不支持二进制 最大连接数限制

有一件事需要注意: 我有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)

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