傳統(tǒng)的 Web 應(yīng)用程序生成發(fā)送到 Web 服務(wù)器端的事件。比如,點(diǎn)擊一個(gè)鏈接會(huì)從服務(wù)器請(qǐng)求一個(gè)新頁(yè)面。
這種從 Web 瀏覽器到 Web 服務(wù)器的時(shí)間類(lèi)型可以稱(chēng)作客服端事件。
隨著 HTML5 的出現(xiàn),WHATWG Web Applications 1.0 引入了一個(gè)從 Web 服務(wù)器到 Web 瀏覽器的事件流,被稱(chēng)作服務(wù)器推送事件(SSE)。使用 SSE 可以不停的將 DOM 事件推送到用戶(hù)的瀏覽器中。
這個(gè)事件流方法會(huì)打開(kāi)一個(gè)到服務(wù)器的持久連接,新消息可用時(shí)發(fā)送數(shù)據(jù)到客戶(hù)端,從而不再需要持續(xù)的輪詢(xún)。
要在 Web 應(yīng)用程序中使用服務(wù)器推送事件,我們需要給文檔添加一個(gè) <eventsource>元素。
<eventsource> 元素的 src 屬性應(yīng)該指向一個(gè) URL,這個(gè) URL 應(yīng)該提供一個(gè) HTTP 持久連接用于發(fā)送包含事件的數(shù)據(jù)流。
這個(gè) URL 將會(huì)指向一個(gè)持續(xù)發(fā)送事件數(shù)據(jù)的 PHP,PERL 或者任意 Python 腳本。下面是一個(gè)簡(jiǎn)單的期望獲得服務(wù)器時(shí)間的 Web 應(yīng)用程序示例。
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
/* Define event handling logic here */
</script>
</head>
<body>
<div id="sse">
<eventsource src="/cgi-bin/ticker.cgi" />
</div>
<div id="ticker">
<TIME>
</div>
</body>
</html>
服務(wù)器端腳本應(yīng)該發(fā)送 Content-type 頭指定類(lèi)型為 text/event-stream,如下所示:
print "Content-Type: text/event-stream\n\n";
設(shè)置 Content-type 之后,服務(wù)器端腳本將發(fā)送一個(gè)后面緊跟事件名稱(chēng)的 Event: 標(biāo)簽。下面的示例將會(huì)發(fā)送一個(gè)以換行符結(jié)束的 Server-Time 作為事件名稱(chēng)。
print "Event: server-time\n";
最后一步是使用 Data: 標(biāo)簽發(fā)送事件數(shù)據(jù),緊隨其后的是以換行符結(jié)束的整數(shù)字符串值,如下所示:
$time = localtime();
print "Data: $time\n";
下面是用 perl 編寫(xiě)的完整 ticker.cgi:
#!/usr/bin/perl
print "Content-Type: text/event-stream\n\n";
while(true){
print "Event: server-time\n";
$time = localtime();
print "Data: $time\n";
sleep(5);
}
讓我們修改一下我們的 Web 應(yīng)用程序來(lái)處理服務(wù)器推送時(shí)間。下面是最終示例:
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
document.getElementsByTagName("eventsource")[0].
addEventListener("server-time", eventHandler, false);
function eventHandler(event)
{
// Alert time sent by the server
document.querySelector('#ticker').innerHTML = event.data;
}
</script>
</head>
<body>
<div id="sse">
<eventsource src="/cgi-bin/ticker.cgi" />
</div>
<div id="ticker" name="ticker">
[TIME]
</div>
</body>
</html>
在測(cè)試服務(wù)器推送事件之前,建議你確保你的 Web 瀏覽器支持這一概念。