WebSockets和Server-Sent Events都能够将数据推送到浏览器。在我看来,它们似乎是相互竞争的技术。它们之间的区别是什么?什么时候你会选择一个而不是另一个?
当前回答
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.
其他回答
Opera, Chrome, Safari支持SSE, Chrome, Safari支持SSE内部的SharedWorker Firefox支持XMLHttpRequest readyState交互,因此我们可以为Firefox创建EventSource polyfil
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:
不支持二进制 最大连接数限制
据caniuse.com网站报道:
98.35%的全球用户原生支持WebSockets 98.03%的全球用户原生支持服务器发送事件
您可以使用仅客户端的polyfill将SSE支持扩展到许多其他浏览器。这在WebSockets中是不太可能的。一些EventSource腻子:
Remy Sharp的EventSource,没有其他库依赖(IE7+) jQuery。Rick Waldron的EventSource Yaffle的EventSource(取代本机实现,规范跨浏览器的行为)
如果你需要支持所有的浏览器,可以考虑使用像web-socket-js, SignalR或socket这样的库。io支持多种传输,如WebSockets, SSE, Forever Frame和AJAX长轮询。这些通常也需要对服务器端进行修改。
了解更多关于SSE的信息:
HTML5 Rocks文章 W3C规范(已发布版本,编辑草案)
了解更多关于WebSockets的信息:
HTML5 Rocks文章 W3C规范(已发布版本,编辑草案)
其他的差异:
WebSockets支持任意二进制数据,SSE只使用UTF-8
Websocket VS SSE
Web Sockets -它是一种协议,通过单个TCP连接提供全双工通信通道。 例如,服务器和浏览器之间的双向通信 由于协议比较复杂,服务器和浏览器不得不依赖websocket库 哪个是socket。io
Example - Online chat application.
SSE(Server-Sent Event) - In case of server sent event the communication is carried out from server to browser only and browser cannot send any data to the server. This kind of communication is mainly used when the need is only to show the updated data, then the server sends the message whenever the data gets updated. For instance a one-way communication between the Server to Browser. This protocol is less complicated, so no need to rely on the external library JAVASCRIPT itself provides the EventSource interface to receive the server sent messages.
Example - Online stock quotes or cricket score website.
它们在语义上有所不同。
Websocket具有“双向数据流”的原生语义含义。
sse的原生语义是“发布-订阅模式”或“请求-响应模式,尽管响应是一个流”。
当然,你可以自己在websocket上实现一层“发布-订阅模式”或“需求模式”。