Ajax是一種從頁面向服務器請求數據的技術,Comet則是一種服務器向頁面推送數據的技術,它可以讓信息近乎實時地被推送到頁面上。php
有兩種實現Comet的方式:長輪詢和流。web
長輪詢是瀏覽器定時向服務器發送請求,而後服務器一直保持鏈接打開,直到有數據可發送。發送完數據後,瀏覽器關閉鏈接,隨即發起一個新的請求。瀏覽器
短輪詢與長輪詢的區別是,服務器接收到請求後,是否當即發送響應。短輪詢是服務器會當即發送響應,不管數據是否有效。而長輪詢是等待發送響應。全部瀏覽器都支持輪詢,使用xhr對象和setTimeOut()就能實現。安全
HTTP流,瀏覽器向服務器發送一個請求,而服務器保持鏈接打開,而後週期性地向瀏覽器發送數據。服務器
在Firefox\Safari\Opera\Chrome中,經過偵聽readystatechange事件及檢測readyState屬性的值是否爲3,就能夠實現HTTP流。當readyState值變爲3時,responseText屬性中就會保存就收到的全部數據,此時,就須要比較此前接收到的數據,決定從什麼位置開始取得最新的數據。代碼以下:websocket
1 function createStreamingClient(url,progress,finished){ 2 var xhr = new XMLHttpRequest(),received = 0; 3 xhr.open("get",url,true); 4 xhr.onreadystatechange = function(){ 5 var result; 6 if(xhr.readyState == 3){ 7 result = xhr.responseText.substring(received); 8 received += result.length; 9 10 progress(result); 11 12 }else if(xhr.readyState == 4){ 13 finished(xhr.responseText); 14 } 15 16 }; 17 xhr.send(null); 18 19 return xhr; 20 } 21 22 var client = createStreamingClient("streaming.php",function(data){ 23 alert("received:"+data); 24 },function(data){ 25 alert("done!"); 26 });
SSE(Server-Sent Events,服務器發送事件)用於建立到服務器的單向鏈接,服務器經過這個鏈接能夠發送任意數量的數據。服務器響應的MIME類型必須是text/even-stream,並且是瀏覽器中的JavaScript API能解析格式輸出。SSE支持短輪詢、長輪詢和HTTP流,並且能在斷開鏈接時自動肯定什麼時候從新鏈接。數據結構
支持SSE的瀏覽器有Firefox 6+、Safari5+、Opera11+、Chrome和iOS4+版Safari。socket
一、SSE API,建立EventSource對象,並傳入一個入口點。傳入的url必須與建立對象的頁面同源(相同的URL模式、域及端口)。ide
var source = new EventSource("myevents.php");
EventSource的實例有個readyState屬性,值爲0表示正鏈接到服務器,爲1表示打開了鏈接,爲2表示關閉了鏈接。加密
包含三個事件,open:在創建鏈接時觸發,message:在從服務器接收到新事件時觸發,error:在沒法創建鏈接時觸發。
source.onmessage = function(event){ var data = event.data;//服務器返回的數據以字符串形式保存在event.data中 //... };
默認狀況下,EventSource對象會保持與服務器的活動鏈接。若是鏈接斷開,還會從新鏈接,適合長輪詢和HTTP流。當即斷開再也不從新鏈接,使用close()。
source.close();
二、事件流,服務器事件會經過一個持久的HTTP響應發送,這個響應的MIME類型爲text/event-stream。響應的格式是純文本。
WebSocket,是一種與服務器進行全雙工、雙向通訊的信道。在JavaScript中建立了WebSocket以後,會有一個HTTP請求發送到瀏覽器以發起鏈接。在取得服務器響應後,創建的鏈接會使用HTTP升級從HTTP協議交換爲Web Socket協議。
websocket使用了自定義的協議,使用的URL模式也有所改變。未加密的鏈接再也不是http://,而是ws://;加密的鏈接不是https://,而是wss://。
使用自定義的協議好處是,可以在客戶端和服務器之間發送很是少許的數據,而沒必要擔憂HTTP那樣字節級的開銷。比較適合移動應用。缺點是安全性和協議的一致性,目前支持的瀏覽器有Firefox6+、Safari5+、Chrome和iOS4+版Safari。
一、websocket API,建立一個實例,傳入絕對路徑的url。同源策略對websocket不適用。
var socket = new WebSocket("ws://www.example.com/server.php");
實例化websocket對象後,瀏覽器就會立刻嘗試建立鏈接。readyState屬性表示當前狀態,值以下:
二、發送和接收數據,只能發送純文本數據,對複雜的數據結構須要進行序列化。服務器發來消息時,就會觸發message事件。
socket.send("hello!"); socket.onmessage = function(event){ var data = event.data; //... };
三、其餘事件,open:成功創建鏈接時觸發,error:在發生錯誤時觸發,鏈接不能持續,close:關閉鏈接時觸發。
WebSocket不支持DOM2級事件偵聽器,必須使用DOM0級語法分別定義每一個事件處理程序。
socket.onopen = function(){ console.log("Connection established") ; }; socket.onerror = function(){ console.log("Connection error"); }; socket.onclose = function(){ console.log("Connection closed"); };
考慮使用SSE仍是Websocket時,首先看是否有自由度創建和維護WebSocket服務器,由於WebSocket協議不一樣於HTTP協議,現有服務器不能用於WebSocket通訊。SSE則能夠經過常規HTTP通訊。其次,是否須要雙向通訊。若是隻須要讀取服務器數據,SSE比較容易實現。若是須要雙向通訊,WebSocket更好一些。組合XHR和SSE也是能實現雙向通訊的。
摘自《JavaScript高級程序設計》