目前客戶端(瀏覽器)和服務端交互大致有以下幾種方式:
1)form表單提交方式,適合訪問量不大,對用戶體驗要求不高的web系統開發,或者頁面整體刷新無傷大雅的場合,通信方向是客戶端提交給服務端,是客戶端主動發起;
2)Ajax方式,特點是用戶體驗好,無需頁面整體刷新,對服務器壓力也小,有利於客戶端和服務端的解耦,也是目前廣為使用的一種客戶端服務端交互方式,它也是通過客戶端發起請求,服務端接受處理,通信方向和form表單相同;
3)server-sent-event,它是服務端主動向客戶端(瀏覽器)發送數據,客戶端監聽並接受,然后處理,通信方向也是單向的,但是和上面兩種相反,是服務端發起,客戶端接受,但是其應用層協議還是基於http的。
4)web socket,這是將以前服務端通信的套接字原理實現在了瀏覽器上,使得瀏覽器和服務端可以相互發送消息,通信方向是雙向的,只要連接一建立,雙方都可以向對方發送數據,無需哪一方先來后來,應用層協議基於WS協議。
上面第3第4由於是HTML5中新添加的功能,所以在很多老版的瀏覽器中(如IE6-IE8)還不支持,因此應用還不夠廣泛.
這里主要實現的是第三種方式,即服務端推送事件,直接上代碼
客戶端代碼
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <script> (function() { var source; if (!!window.EventSource) { source = new EventSource('http://localhost/server.php'); } source.onmessage=function(e) { var oSpan=document.createElement('span'); oSpan.innerHTML=e.data+"<br>"; var oDiv=document.querySelector("#div1"); oDiv.appendChild(oSpan); } })(); </script> <div id="div1"></div> </body> </html>
以上代碼構造一個eventSource對象,指向一個服務端后台PHP文件,這個對象是HTML5中的服務端推送事件API封裝對象,然后添加onmessage事件,用來監聽服務端發送過來的消息,服務端一有消息發送,就會執行這個事件的回調函數,這里讓它接收到數據之后將其包裹在span中並將這個span插入到div中。
服務端代碼server.PHP
<?php header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); function sendMsg($id, $msg) { echo "id: $id" . PHP_EOL; echo "data: $msg" . PHP_EOL; echo PHP_EOL; ob_flush(); flush(); } for($i=0;$i<=1000;$i++) { $serverTime = time(); sendMsg($serverTime, 'server time: ' . date("h:i:s", time())); sleep(2); }
首先要設定其發送給客戶端http報文中的首部
header('Content-Type: text/event-stream');這是服務端推送事件特定的MIME類型,
header('Cache-Control: no-cache');表示不讓瀏覽器進行緩存
然后每隔兩秒向客戶端發送一個時間戳,客戶端接收到之后,顯示到div中,效果如下:
有了這種通信方式,我們制裁采用的Ajax長輪詢的方式來模擬服務器端推送事件就可以不用了,如果服務端收到一些需要通知客戶端的信息,那么可以直接發送給客戶端,而不必等待其發送請求。