目前客戶端(瀏覽器)和服務端交互大致有以下幾種方式:
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長輪詢的方式來模擬服務器端推送事件就可以不用了,如果服務端收到一些需要通知客戶端的信息,那么可以直接發送給客戶端,而不必等待其發送請求。
