傳統的網頁技術
都是單向的,也就是瀏覽器向 網頁伺服器 發出請求,網頁伺服器 依據 瀏覽器的要求(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/