雙向通訊之SSE

簡介

基於 HTTP 協議,一個客戶端去從服務器端訂閱一條流,以後服務端能夠發送消息給客戶端直到服務端或者客戶端關閉該「流」跨域

特色

  • 創建瀏覽器與服務器之間的通訊渠道,而後服務器向瀏覽器推送信息
  • SSE 是單向通道,只能服務器向瀏覽器發送,由於流信息本質上就是下載
  • 使用 HTTP 協議,現有的服務器軟件都支持。WebSocket 是一個獨立協議。
  • 屬於輕量級,使用簡單,兼容性良好

客戶端

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);
複製代碼

服務器端

  • 事件流對應MIME格式爲text/event-stream,並且其基於HTTP長鏈接。針對HTTP1.1規範默認採用長鏈接,針對HTTP1.0的服務器須要特殊設置。
  • event-source必須編碼成utf-8的格式
  • 每一次發送的信息,由若干個message組成,每一個message之間用\n\n分隔。每一個message內部由若干字段組成,每一字段都是以下格式。
[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);
    })
});

複製代碼

ssestream pass through 一種轉換流

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);
    })
    
});

複製代碼
相關文章
相關標籤/搜索