HTML5 – Server Sent Events
隨著Web應(yīng)用程序的發(fā)展,實(shí)時(shí)通信變得越來越重要。愛掏網(wǎng) - it200.com傳統(tǒng)的HTTP請求只能實(shí)現(xiàn)客戶端對服務(wù)器的請求和響應(yīng),但是在某些場景下,這種方式顯得力不從心,比如股票交易、多人在線游戲等需要實(shí)時(shí)更新的應(yīng)用場景。愛掏網(wǎng) - it200.com這時(shí)候,就需要用到Server Sent Events(SSE)。愛掏網(wǎng) - it200.com
SSE使用HTTP協(xié)議,通過一種全新的方式允許服務(wù)器向客戶端推送數(shù)據(jù),而不需要客戶端發(fā)出請求。愛掏網(wǎng) - it200.com這種方式通常被用于實(shí)時(shí)更新:包括在線獨(dú)家新聞、股票報(bào)價(jià)、聊天室等。愛掏網(wǎng) - it200.com
SSE主要是由JavaScript的EventSource對象發(fā)起。愛掏網(wǎng) - it200.com代碼示例:
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("sse.php");
source.onmessage = function(event) {
document.getElementById("result").innerHTML += event.data + "<br>";
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
客戶端JavaScript通過使用EventSource對象與服務(wù)器協(xié)作的方式,來實(shí)現(xiàn)從服務(wù)器到客戶端的實(shí)時(shí)推送。愛掏網(wǎng) - it200.com服務(wù)器發(fā)送更新時(shí),事件源都會(huì)創(chuàng)建一個(gè)新的事件對象,該事件對象中包含了當(dāng)前服務(wù)器發(fā)回的全部數(shù)據(jù)。愛掏網(wǎng) - it200.com
服務(wù)器端如何實(shí)現(xiàn)SSE呢?服務(wù)器端代碼示例如下:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
data = "data: The server time is: " . date('H:i:s') . "\n\n";
echodata;
flush();
這段服務(wù)器端代碼會(huì)向客戶端發(fā)送當(dāng)前服務(wù)器的時(shí)間(當(dāng)做測試),并設(shè)置Content-Type為”event-stream”,表示這是一種SSE推送。愛掏網(wǎng) - it200.com
服務(wù)器端的跨域問題
由于SSE使用的是HTTP協(xié)議,因此存在跨域問題。愛掏網(wǎng) - it200.com在跨域請求的情況下,服務(wù)器需要設(shè)置Access-Control-Allow-Origin頭信息。愛掏網(wǎng) - it200.com代碼示例如下:
header("Access-Control-Allow-Origin: *");
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
data = "data: The server time is: " . date('H:i:s') . "\n\n";
echodata;
flush();
這里的“*”表示接受任何跨域請求,也可以設(shè)置為具體的域名,以滿足不同的業(yè)務(wù)需求。愛掏網(wǎng) - it200.com
事件類型
SSE支持三種事件類型:Message(一般事件)、Error(錯(cuò)誤事件)和Close(關(guān)閉事件)。愛掏網(wǎng) - it200.com
客戶端通過onmessage和onerror兩個(gè)事件處理程序來處理不同的事件類型。愛掏網(wǎng) - it200.com
例如,在每一個(gè)消息之前,服務(wù)器會(huì)發(fā)送一個(gè)id事件:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
data = "id: " .id . "\n";
data .= "data: " .message . "\n\n";
echo $data;
flush();
在JavaScript中,可以導(dǎo)入這個(gè)事件,偵聽它,并進(jìn)行處理:
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("sse.php");
source.addEventListener('id', function(event) {
console.log('Server sent an ID: ' + event.data);
}, false);
source.onmessage = function(event) {
document.getElementById("result").innerHTML += event.data + "<br>";
};
source.onerror = function(event) {
console.log('An error occurred and the connection was closed.');
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
瀏覽器支持情況
遺憾的是,IE瀏覽器不支持SSE,支持SSE的僅有Chrome、Firefox、Safari等主流現(xiàn)代瀏覽器。愛掏網(wǎng) - it200.com但是,在不支持SSE的瀏覽器中,可以通過使用Polyfills來實(shí)現(xiàn)SSE的兼容。愛掏網(wǎng) - it200.comPolyfills是一種JavaScript的常見技術(shù),它可以在不支持某些特性的瀏覽器中模擬這些特性。愛掏網(wǎng) - it200.com
Polyfills實(shí)現(xiàn)
Polyfills主要用于填充瀏覽器在實(shí)現(xiàn)某些特性時(shí)所遺漏的部分,比如SSE。愛掏網(wǎng) - it200.com我們可以使用EventSource-js庫來實(shí)現(xiàn)Polyfills。愛掏網(wǎng) - it200.com
<script src="https://cdn.jsdelivr.net/npm/event-source-polyfill/dist/eventsource.min.js"></script>
通過引入這個(gè)Polyfills庫,我們就可以在IE瀏覽器中使用SSE了。愛掏網(wǎng) - it200.com
結(jié)論
Server Sent Events(SSE)是一種實(shí)現(xiàn)服務(wù)器向客戶端推送數(shù)據(jù)的Web API。愛掏網(wǎng) - it200.com它使用HTTP協(xié)議,通過一種全新的方式允許服務(wù)器向客戶端推送數(shù)據(jù),而不需要客戶端發(fā)出請求。愛掏網(wǎng) - it200.comSSE可以廣泛應(yīng)用于多種場景下,比如在線獨(dú)家新聞、股票報(bào)價(jià)、聊天室等需要實(shí)時(shí)更新的應(yīng)用場景。愛掏網(wǎng) - it200.com但是需要注意的是,由于IE瀏覽器不支持SSE,因此在不支持SSE的瀏覽器中,需要使用Polyfills來實(shí)現(xiàn)SSE的兼容。愛掏網(wǎng) - it200.com