基於 HTTP 協議,一個客戶端去從服務器端訂閱一條流,以後服務端能夠發送消息給客戶端直到服務端或者客戶端關閉該「流」跨域
let eventSource = new EventSource('/clock'); // url能夠同域,也能夠跨域
let clock = document.querySelector("#clock");
// 鏈接打開
source.onopen = function (event) {
// ...
};
// 監聽服務器返回的消息
eventSource.onmessage = (e) => {
let message = e.data;
clock.innerHTML = message;
}
// 監聽鏈接請求失敗
eventSource.onerror = function(err){
console.log(err);
}
// 關鏈接
eventSource.close();
// 監聽自定義事件
eventSource.addEventListener('foo', function (e) {
var data = e.data;
}, false);
複製代碼
[field]: value\n
複製代碼
field須要使用下面4個規範定義好的字段:瀏覽器
Event: 自定義事件類型
Data: 發送的數據
ID: 每一條事件流的ID
Retry: 告知瀏覽器在全部的鏈接丟失以後從新開啓新的鏈接等待的時間,在自動從新鏈接的過程當中,以前收到的最後一個事件流ID會被髮送到服務端
複製代碼
使用例子:bash
app.get('/clock', (req, res) => {
res.header('Content-Type', 'text/event-stream'); // 特定
let timer = setInterval(() => {
res.write(`id:${counter++}\nevent:message\ndata:${new Date().toLocaleDateString()}\n\n`);
}, 1000);
res.on('close', () => {
clearInterval(timer);
})
});
複製代碼
app.get('/clock', (req, res) => {
const sseStream = new SseStream(req);
sseStream.pipe(res);
const pusher = setInterval(() => {
sseStream.write({
id: counter++,
event: 'message',
retry: 20000, // 告訴客戶端,若是斷開鏈接後,20秒後再重試鏈接
data: new Date().toLocaleDateString()
});
}, 1000);
res.on('close', () => {
clearInterval(pusher);
sseStream.unpipe(res);
})
});
複製代碼