server push: 有两个版本, http1 的 server push 和 http2 的 server push.
http1 的 server push: 需要服务端代码, 浏览器共同支持, 简单说在浏览器发起请求后, 服务端响应一个 "Content-type: multipart/x-mixed-replace;boundary=-- boundaryString --" 的文档类型, 然后由服务端代码循环推送内容, 浏览器每接收一次就渲染一次, 达到桌面程序不刷新页面就更新内容的效果, 这个技术流行于上个世纪的 95-98 年左右, 主要应用于聊天室这类可以实现不刷新滚屏, 本人当时也在计算机报上发表过相关的文章, 但是当时服务端编程架构和技术比较落后, 无论是 c/c++/perl 为代表的 cgi, 还是 PHP,ASP 等基本都是基于进程来处理请求, 系统性能消耗非常大. 所以这个技术并没有广深流行.
http2 的 server push: 通过服务端容器或 httpserver 的配置, 在请种某一资源时主动把相关资源推送给浏览器的技术. 其作用有点象 mhtml, 把相关资源打个包一起给你, 不要浏览器请求 ->解析 ->再请求直到请求的内容中没有新的资源请求再一起渲染.
敲黑板: 但是 http2 的 server push 只是推送已经存在的静态资源, 其实并没有什么大的卵用. 一是所有文档相关的资源要一个一个配置, 比如 1.html 相关 1.CSS,2.html 相关 2.css, 你要一个一个去配置. 除非是所有页面都引用的全局 css 或 js 等资源, 其它情况并没有多少人会去使用这种技术, 而且 CDN 为主的资源分发环境下, 不知道真正使用它的能有多少人. 当然任何技术都能提供一种方案, 在特殊情况下仍然可以作为一种补充. 但是基于请求验证的安全性会被主动 push 大大减弱.
websocket 其实并不应该拿在一起说, 因为它不是 push 技术, 它只是一个普通的双工 socket, 和你在应用程序打开一个 socket 没有区别, 只是它运行在浏览器的沙箱中而不是操作系统进程中. 如果要拿它说事, 那么, 它和 applet,activex 都甚至 flash 等插件应该一起说. 只不过它更底层, 就象你同样可以用 new Socket("serveraddr",80)和 new HttpReq("serveraddr")访问一个 URL 一样, 只不过 HttpReq 把 Socket 封装了.
SSE: 这个有点象 http1 的 server push 了, 只不过消息格式更简单, 而且在现代服务端架构 (轻量 socket 连结, 没有消息传输时只保持文件描述符) 和编程技术 (线程或纤程处理请求) 下, 服务端可以支持大量的这种长连结, 所以具有较广泛的应用场景.
服务端:
- Content-Type: text/event-stream
- Cache-Control: no-cache
- Connection: keep-alive
field: valuen 不断发送.
因为现在 js 框架的成熟, 不刷新更新数据已经非常方便, 但是对于不同浏览器的实现不同, 并不是所有浏览器都是保持长连结, 只不过是异步对象封装了这个过程, 象 IE 这种一次 POST 请求都能分开两次连接的怪胎, 你无法保证实际上你的客户端和服务端到底进行了多少次连结, 那么, 使用 SSE 可以确认我只打开一个连结, 一次请求后, 服务端会源源不断把数据更新给我.
来源: https://www.thinksaas.cn/group/topic/839598/