前两天写了一篇SSE的文章,有很多朋友有不同的看法,还有一些更深层次的技术方案考量,让我也是受益颇深。
所以结合上次朋友们的讨论和自己整理的SSE更深层次的内容,跟大家分享一下。如果有不同见解欢迎留言讨论,上期文章留下方便大家查阅《消息提醒别再用 WebSocket 和轮询,有更好的方案!》。
有朋友表示浏览器限制 http 连接不能超过6个,使用 SSE 会不会导致其他问题?
这个说法没什么问题!
如果抠字眼的表达其实是:现代主流浏览器对于对同一个服务器或同一个域名的HTTP连接数一般限制在6~8个,这个限制的主要目的是防止客户端对服务器资源的过度消耗。
请注意!这里的限制是:每个客户端(即访问你网站的每个用户)浏览器对同一个域名能够同时开启的连接数量。
解决方案:
- 拆分:通过将不同的资源分布在不同的子域名下来绕过浏览器对于每一个域名连接数的限制。这是因为每个子域名都有自己的连接池,通过分散资源的方式变相增加总的并发连接数。(Ps: 这里其实服务端使用多个端口号达到的效果是一样的,本质上就是绕过浏览器限制)
- 合并:将小图片采用精灵图(雪碧图)的方式,将CSS/JavaScript等文件进行合并,减少系统需要加载的文件数量。还可以将比较小的CSS/JavaScript合并进 HTML 文件,减少请求数。
- 异步:通过懒加载或者推迟加载的方式让资源有序加载,避免阻塞。
- CDN:其实CDN本质上就是把资源拆分了,只不过CDN本身相当于一个外包,将你的请求分发给不同的域名。
- 升级:连接数限制本身是在HTTP/1.x协议中规定的,但是在HTTP/2协议中由于支持了多路复用,减少了连接数,变相的让连接数不再成为限制。
所以如果业务和SSE技术契合的情况下,使用SSE不会有问题!
SSE 和 HTTP长连接 到底有没有区别?
其实是有的!
SSE是允许服务端向客户端推送的技术,本质上是单向的数据流。它只是基于HTTP协议进行通信,事件流格式也是通过 UTF-8 进行文本传输,只是以 text/event-stream MINI类型标识。
而 HTTP长连接 是一个较为宽泛的概念,这种长连接的实现方案有很多种,比如:Keep-Alive,HTTP/2 多路复用机制,甚至WebSocket也算是长连接的一种方式。
SSE 到底是不是轮询?它和轮询到底有什么区别?
首先明确,SSE不是轮询!
在主动性上来说,轮询是客户端主动发起请求向服务端来获取最新信息,而SSE则相反,是服务端主动向客户端推送更新。只不过SSE是提前通过HTTP协议建立了通道。
轮询就像是从你家去超市买东西,轮询就好像你一次次的从家里出发,去超市买完东西再回家。
SSE就像是你从家出发去超市告诉了售货员给你送货上门,你直接回家了,然后超市一趟一趟给你送。
从资源消耗的角度上说,轮询必然比SSE消耗的资源要多。无论是否存在数据更新,轮询要求客户端都要发起请求(即便是长轮询也有其超时时长),而SSE在建立连接后,只是数据有更新时才会有传输。
使用http设置请求头Transfer-Encoding为chunked和SSE是否完全一致
不一致!
诚实的讲,这个问题我还真不清楚,也是查资料才闹明白的,看来还是兄弟们水平高。
通过设置HTTP请求头中的Transfer-Encoding为chunked并让服务端每接收到一次消息就flush一次,是可以在某种程度上模拟类似SSE的。
因为它的确模拟到了SSE的流式数据传输和实时传输。
但是这两种方式仍然存在相当大的区别,实战层面最核心的就是断线重连机制。
SSE是具备自动重连机制的,而Chunked不存在断线重连,需要手动实现。并且对于SSE的数据流,浏览器提供了EventSource接口简化操作。但是Chunked需要手动去管理这一切,上项目以后太麻烦。
对于其他方面的区别就是协议规范、消息格式以及事件处理方面的区别。
在摸索中与大家共勉,在折腾中慢慢进步,非常感谢朋友们的留言指正。