《高級前端3.2》JavaScript數據推送——Comet,WebSocket,SSE,NodeJs,Express


JavaScript數據推送主要致力於webapp的在線推送服務,不用我們每次都像服務器去發送Ajax請求而主動從Server端推送數據到本地。

數據推送進化史:

1. HTTP協議簡易輪詢,保持着一個鏈接不放,或者通過前端不停的向后端發送請求

2. H5更新后有了WebSocket大大改善了雙向和單向推送數據的便利性

3. SSE(Server-Send Event):服務器推送數據的新方式

 

Comet:基於 HTTP 長連接的服務器推送技術

本課時介紹Comet:基於 HTTP 長連接的服務器推送技術,Comet 是一種 Web 應用架構。服務器端會主動以異步的方式向客戶端程序推送數據(Ajax請求死循環),而不需要客戶端顯式的發出請求。Comet 架構非常適合事件驅動的 Web 應用,以及對交互性和實時性要求很強的應用,如股票交易行情分析、聊天室和 Web 版在線游戲等。

 

1.先來看一個最簡單的ajax請求json數據例子:

index.html

<meta charset="utf-8">
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript">
    $.ajax({
        url: 'data.php',
        dataType: "json",
        success: function(data){
            console.log(data);
        }
    });
</script>

data.php

<?php 
header('Content-type: application/json;charset=utf-8');
$res = array('success'=>'ok', 'text'=>'我是測試的文本');
echo json_encode($res);
?>

這樣前端就能獲取后端數據並輸出。下面我們來模擬后端不斷推送數據到前端:

一種辦法是前端循環不斷發送ajax請求

 

2.前端jQuery的Ajax不斷發送請求:

index.html

<meta charset="utf-8">
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript">
function conn(){
    $.ajax({
        url: 'data.php',
        dataType: "json",
        success: function(data){
            console.log(data);
            conn();
        }
    });
}
conn();    
</script>

data.php

<?php 
header('Content-type: application/json;charset=utf-8');
header("Cache-Control:max-age=0");    //設置沒有緩存
sleep(1);
$res = array('success'=>'ok', 'text'=>'我是測試的文本');
echo json_encode($res);
?>

但是這樣的連接輪詢,網絡請求浪費非常明顯,我們也可以讓后端服務器來循環做這件事情,看下面例子

 

3.原生Ajax,服務器隔一段時間推送一次(后端循環,用ob_flush()和flush()吐數據)

data.php

<?php 
// header('Content-type: application/json;charset=utf-8');
header("Cache-Control:max-age=0");    //設置沒有緩存
$i = 0;
while ($i<9) {
    $i++;
    // $res = array('success'=>'ok', 'text'=>'我是測試的文本');
    // echo json_encode($res);
    sleep(1);
    $radom = rand(1,999);
    echo $radom;
    echo '<br/>';
    ob_flush();    //輸出緩存,必須和flush()一起使用
    flush();    //緩存吐到瀏覽器
}
?>

前台js(原生js實現ajax,並當狀態改變時,進行輸出) 參考:http://www.cnblogs.com/woodk/p/5191935.html

var getXmlHttpRequest = function() {
    if (window.XMLHttpRequest) {
        //主流瀏覽器提供了XMLHttpRequest對象
        return new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        //低版本的IE瀏覽器沒有提供XMLHttpRequest對象
        //所以必須使用IE瀏覽器的特定實現ActiveXObject
        return new ActiveXObject("Microsoft.XMLHttpRequest");
    }

};
var xhr = getXmlHttpRequest();
xhr.onreadystatechange = function() {
    console.log(xhr.readyState);
    if (xhr.readyState === 3 && xhr.status === 200) {
        //獲取成功后執行操作
        //數據在xhr.responseText
        console.log(xhr.responseText);
    }
};
xhr.open("get", "data.php", true);
xhr.send("");

 

 

基於WebSocket 的推送方案

在瀏覽器中通過http僅能實現單向的通信,comet可以一定程度上模擬雙向通信,但效率較低,並需要服務器有較好的支持; HTML5定義了WebSocket協議,能更好的節省服務器資源和帶寬並達到實時通訊。

《使用Node.js+Socket.IO搭建的WebSocket實時通信聊天室例子》http://www.open-open.com/lib/view/open1402479198587.html

這個例子先安裝nodejs,然后用npm安裝express和socket.io,非常簡潔地實現了一個聊天室應用。

效果演示:http://demo.plhwin.com/chat/

源碼可以到作者github下載:https://github.com/plhwin/nodejs-socketio-chat

 

 

SSE(Server-Send Event):服務器推送數據的新方式

相對於WebSocket的雙向通信,SSE更主要用於服務器向客戶端推送數據。

SSE的實現相當簡潔方便,可以用任何后端語言,就像新增加一個頁面一樣,可以不添加任何新的組件。

使用SSE時,如果需要由客戶端向服務器端傳數據,一般是另外用一個Ajax。(而WebSocket是真正的雙向通信,只是他的實現一般都要加入新的組件,也比SSE更為復雜些)

SSE和WebSocket的取舍,主要還是看客戶端向服務器端傳輸數據的頻率。如果是1次/秒,那肯定是用WebSocket;如果頻率比較低,可以選擇更方便的SSE。

《HTML5新技術:SSE挑戰WebSocket》http://www.php230.com/weixin1416305260.html

SSE小例子(PHP后端頁面):http://www.cnblogs.com/woodk/articles/5192089.html


免責聲明!

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



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