SSE(Server-Sent Events)
SSE,基于事件流的服务端推送,是HTML5的新特性,除开IE/Edge的主流浏览器都支持。它允许客户端与服务端建立连接后,服务端单方面向客户端推送实时消息。是基于HTTP的长连接实现的。
特性
- 建立连接后,只能服务端向客户端推送消息
- 基于HTTP长连接,消息都是从同一个TCP返回
- 实时性,服务端向客户端推送客户端需要的,或者服务端想推送的消息
关键
- 前端通过EventSource或者fetch发起请求
- fetch时需要指定
Accept:text/event-stream
- 通过
onmessage
拿到流数据
- fetch时需要指定
- 请求是GET请求
- 服务端返回
Content-Type:text/event-stream
- 数据格式
// id: 当前消息的 id
// event: 当前消息的类型,根据业务需要自行定义。新闻:news
// data - 这条消息的内容,只能为文本类型 —— 也可以是JSON字符串或者自定义的字符串格式
// retry - 值必须是数字 —— 如果连接中断,客户端应该间隔多少毫秒再尝试重新连接
id: D420B6E8-2F51-4235-B778-5C1C494681E8
event: city-notification
retry: 3000
data: Plainville
id: 3AC67AA0-2852-4D30-9103-23CEF4B43D6D
event: city-notification
retry: 3000
data: Bellevue
想传二进制!
- 如果想传输二进制,需要先转换格式(如转换位base64字符串,到达客户端后再转回来)
原理
关键在于“服务端告诉客户端——本次消息需要通过事件流的方式发送,客户端支持并接收后不会断开本次连接(即长连接)”。可以看成是一个下载的过程。
Server Push(http2.0)
它是http2.0的一个新特性。是一种“允许服务器预测客户端可能需要哪些资源,并主动将这些资源推送到客户端”。
特性
- 需要开发者配置才支持,其他特性都是浏览器或者服务器自己实现
- http2.0才行,不支持http2.0的端不能享受该特性
问题
- 如果浏览器缓存过推送的资源,那么这次推送就是浪费带宽,即使本次的推送是新于缓存的数据,浏览器也会先采用原来的缓存。
- 所以建议只对第一次访问的客户端采取推送的能力(配置),如判断是否有cookie。有:不推
- 如果主动推送的资源太多,反而不利于性能的提升
- 建议只推送css,加快DOM渲染即可
过程
以一个HTTP2.0请求HTML描述该过程。
当向服务端请求一个HTML,如果HTML中有css js资源,那么意味着接下来浏览器会再次请求这些资源。而Server Push这个特性不需要浏览器发送多个请求,而是主动返回这些资源,也就是说只需要一次请求浏览器就得到了所有资源。这个返回还利用了http2.0的多路复用的能力,这些资源的推送是并行的,加快了浏览器获取资源的速度,提高性能。
以上是对SSE和Server
Push的简单描述,同是服务端单方面推送,应用场景不同,本身不应该产生对比,反而应该是SSE和WebSocket比一下🤣。