SSE與WebSocket


  Ajax是一種從頁面向服務器請求數據的技術,Comet則是一種服務器向頁面推送數據的技術,它能夠讓信息近乎實時地被推送到頁面上。

  有兩種實現Comet的方式:長輪詢和流。

  長輪詢是瀏覽器定時向服務器發送請求,然后服務器一直保持連接打開,直到有數據可發送。發送完數據后,瀏覽器關閉連接,隨即發起一個新的請求。

  短輪詢與長輪詢的區別是,服務器接收到請求后,是否立即發送響應。短輪詢是服務器會立即發送響應,無論數據是否有效。而長輪詢是等待發送響應。所有瀏覽器都支持輪詢,使用xhr對象和setTimeOut()就能實現。

   HTTP流,瀏覽器向服務器發送一個請求,而服務器保持連接打開,然后周期性地向瀏覽器發送數據。

  在Firefox\Safari\Opera\Chrome中,通過偵聽readystatechange事件及檢測readyState屬性的值是否為3,就可以實現HTTP流。當readyState值變為3時,responseText屬性中就會保存就收到的所有數據,此時,就需要比較此前接收到的數據,決定從什么位置開始取得最新的數據。代碼如下:

 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             });
View Code

  SSE(Server-Sent Events,服務器發送事件)用於創建到服務器的單向連接,服務器通過這個連接可以發送任意數量的數據。服務器響應的MIME類型必須是text/even-stream,而且是瀏覽器中的JavaScript API能解析格式輸出。SSE支持短輪詢、長輪詢和HTTP流,而且能在斷開連接時自動確定何時重新連接。

  支持SSE的瀏覽器有Firefox 6+、Safari5+、Opera11+、Chrome和iOS4+版Safari。

  1、SSE API,創建EventSource對象,並傳入一個入口點。傳入的url必須與創建對象的頁面同源(相同的URL模式、域及端口)。

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();

  2、事件流,服務器事件會通過一個持久的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。

  1、websocket API,創建一個實例,傳入絕對路徑的url。同源策略對websocket不適用。

var socket = new WebSocket("ws://www.example.com/server.php");

  實例化websocket對象后,瀏覽器就會馬上嘗試創建連接。readyState屬性表示當前狀態,值如下:

  • WebSocket.OPENING(0),正在建立連接
  • WebSocket.OPEN(1),已經建立連接
  • WebSocket.CLOSING(2),正在關閉連接
  • WebSocket.CLOSE(3),已經關閉連接

  2、發送和接收數據,只能發送純文本數據,對復雜的數據結構需要進行序列化。服務器發來消息時,就會觸發message事件。 

socket.send("hello!"); 
socket.onmessage = function(event){
   var data = event.data;
   //...  
};

  3、其他事件,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高級程序設計》  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM