众所周知,AJAX的出现是前端快速发展的一个标志,同时也是先后端得以分离的重要基础。做为一个C/S网络的web系统,网络通讯在发挥着举足轻重的做用。
大部分的场景下,咱们是主动触发AJAX去调取后端数据,可是总有那么些场景是后端数据更新了再推送给前端。
本文则试着和读者一块儿对这个数据推送的需求进行技术方案的探究。php
首先,列一个经常使用可选的技术清单html
websocket前端
SSE(Server-Sent Event)html5
轮询(长轮询)web
数据推送是由服务端选择向客户端发送新数据。
当数据源有新数据时,服务端能马上将它发送给一个或多个客户端,而不用等客户端来请求。后端
数据推送有两种替代方案:无更新方案和数据拉取方案。浏览器
数据拉取和数据推送的功能目标是一致的:让用户看到最新的数据。但数据推送有一些优点,即更低的延迟。
可是在数据拉取的方式中,权衡会让你很纠结,要缩短延迟就要提升轮询的频次,要节省带宽和链接就要下降轮询的频次。服务器
webSocket是html5新引入的技术,容许后台随时向前端发送文本或者二进制消息,WebSocket是一种全新的协议,不属于http无状态协议,协议名为”ws”,
这意味着一个websocket链接地址会是这样的写法:ws://wilsonliu.cn:8080/webSocketServer
。ws不是http,因此传统的web服务器不必定支持,
须要服务器与浏览器同时支持,WebSocket才能正常运行,目前的支持还不广泛,须要特别的web服务器和现代的浏览器。websocket
// 在这里略去服务端实现,着重于比较客户端。 客户端实现可参考[参考连接2] var ws = new WebSocket("ws://localhost:4000"); // 这里新建一个websocket链接,ws此时是一个websocket句柄 ws.onopen = function(){ // 常见的前端事件回调 console.log("握手成功"); }; ws.onmessage = function(e){ // 事件有 open,close,error,message console.log("信息:" + e.data); // 输出后台返回的信息 }; ws.send("测试")
SSE 是 HTML5 的 Server-Sent Events
缩写,服务器端发送的事件。网页自动获取服务器端的数据更新。
以前网页获取服务器端更新的数据是须要先想服务器发送状况,肯定是否有数据变动,而后获取,而SSE是服务器 一旦有数据更新就主动向网页发送数据。网络
// 前端 var es = new EventSource("sse.php"); // 创建链接,EventSource只能单向通讯,没有send函数 es.addEventListener("message", function(e){ // EventSource有3个事件, open,error,message console.log(e.data); },false); // php <?php header("Content-Type: text/event-stream"); while(true){ echo "data:".date("Y-m-d H:i:s")."\n\n"; @ob_flush();@flush(); // 当即将数据返回给客户端,而不是缓冲起来成批发送 sleep(1); }
轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后立刻返回响应信息并关闭链接。
优势:后端程序编写比较容易。
缺点:请求中有大半是无用,浪费带宽和服务器资源。
function poll() { setTimeout(function() { $.get("/path/to/server", function(data, status) { console.log(data); // 发起下一次请求 poll(); }); }, 10000); }
长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住链接,直到有新消息才返回响应信息并关闭链接,客户端处理完响应信息后再向服务器发送新的请求。
优势:在无消息的状况下不会频繁的请求,耗费资源小。
缺点:服务器hold链接会消耗资源,返回数据顺序无保证,难于管理维护。
websocket是一种更为复杂的服务端实现技术,但它是真正的双向传输技术,既能从服务端向客户端推送数据,也能从客户端向服务端推送数据。
websocket和SSE的浏览器支持率差很少。
SSE优点。
既存基础设施优点:不须要添加任何新组件,也不须要新建虚拟机,弄一个新的IP或新的端口号。
服务端更加简洁
文本协议,更方便调试
websocket优点
双向数据流(使用SSE时,通常经过独立的AJAX请求从客户端向服务端传送数据)
WilsonLiu's blog首发地址:http://blog.wilsonliu.cn