輪詢 Polling、Comet、長時間輪詢 Long Polling

2016081208:11
 

傳統的網頁技術

都是單向的,也就是瀏覽器向 網頁伺服器 發出請求,
網頁伺服器 依據 瀏覽器的要求(GET/POST...) 送出相關網頁資料後 就斷線 (無狀態協議)
網頁伺服器並無法主動、定時發送資料到瀏覽器

無法解決需要即時性資訊的服務
如股市行情、聊天室、選舉開票..這種數據隨時在變動,必需立即傳遞給瀏覽器(用戶端) 更新畫面內容

後來發展出幾種新技術來解決類似問題:
Polling、Long Polling 與 Streamings
 
** 這三種連線方式仍舊是單向的資料傳輸: Server --> Client


 

輪詢 Polling

說到底,Polling 也不是新技術
只是讓瀏覽器每隔一段時間 (如每秒) 就自動送出一個 HTTP request 到伺服器,讀取最新的資料
不就是自動化的 F5 ?!
最早期(10幾年前) 的聊天室就是採用這做法 (當年也只有、只能用這種方式)

早期尚無 Ajax 技術時,聊天室中常見這樣的做法
即是在網頁加上這樣的語法,即可每秒自動更新整個網頁

<meta http-equiv="refresh" content="1">

或是用 JavaScript 的 setInterval() 定時更新網頁

這做法比較大的問題是
1.要定時發 request ,到底間隔多久,一秒、兩秒...?若聊天室中有 3、500人時 同一時間 server 會收到 3、500 個 Request
2.有可能連續幾次的 requst 都是取得相同的網頁資料 (因為 server 端的網頁/數據並無變化),浪費網路資源、server資源


 

Comet

Comet 「彗星」
這個技術就像彗星一樣,後面拖著一個長長的尾巴
Client 發出一個請求 Request 後,Server 不將此連線中斷 ( 一般的 request 都是在資料傳輸完就斷線/結束)
Server 一有新的資料時就送出給 Client

Comet 的實作方式有兩種:
長時間輪詢 Long polling 、 串流 Streaming

ref wiki Comet
 

長時間輪詢 Long Polling

Client 發出一個請求 Request 後,Server 不將此連線中斷,Server 等待著有資料更新時就送出資料給 Client

以 PHP 來解釋

<?php

// set php runtime to unlimited
set_time_limit(0);

// where does the data come from ? In real world this would be a SQL query or something
$data_source_file = 'data.txt';

// main loop
while (true) {  //一個永不停止的迴圈

    // if ajax request has send a timestamp, then $last_ajax_call = timestamp, else $last_ajax_call = null
    $last_ajax_call = isset($_GET['timestamp']) ? (int)$_GET['timestamp'] : null;

    // PHP caches file data, like requesting the size of a file, by default. clearstatcache() clears that cache
    clearstatcache();
    // get timestamp of when file has been changed the last time
    $last_change_in_data_file = filemtime($data_source_file);

    // if no timestamp delivered via ajax or data.txt has been changed SINCE last ajax timestamp
    if ($last_ajax_call == null || $last_change_in_data_file > $last_ajax_call) {

        // get content of data.txt
        $data = file_get_contents($data_source_file);

        // put data.txt's content and timestamp of last data.txt change into array
        $result = array(
            'data_from_file' => $data,
            'timestamp' => $last_change_in_data_file
        );

        // encode to JSON, render the result (for AJAX)
        $json = json_encode($result);
        echo $json;

        // leave this loop step
        break;

    } else {
        // wait for 1 sec (not very sexy as this blocks the PHP/Apache process, but that's how it goes)
        sleep( 1 );
        continue;
    }
}


參考 https://github.com/panique/php-long-polling


Long polling  仍是單向的 Server 送資料給 Client
Client 若要傳資料給 Server,仍要另開新的連線 (Request)

 

串流 Streaming

     沒研究



 

WebSocket

接著 2011年出現的 WebSocket 可進行全雙工的通訊協定
Client、Server 間可以在同一個連線 (不斷線) 中互相傳遞資料 (可傳送文字或二進位資料)

 
WebSocket 是HTML5開始提供的一種在單個 TCP 連線上進行全雙工通訊的協定。
WebSocket通訊協定於2011年被IETF定為標準RFC 6455,WebSocketAPI被W3C定為標準。

在WebSocket API中,瀏覽器和伺服器只需要做一個交握的動作,然後,瀏覽器和伺服器之間就形成了一條快速通道。兩者之間就直接可以資料互相傳送。


by 維基百科


WebSocket 網站上有一些 deom 網站:
https://www.websocket.org/demos.html

這是各大股市的即時指數、各個貨幣匯率表:
http://demo.kaazing.com/forex/