后端數據推送-EventSource


服務器發送事件(以下簡稱SSE)是HTML 5規范的一個組成部分,可以實現服務器到客戶端的單向數據通信。通過SSE,客戶端可以自動獲取數據更新,而不用重復發送HTTP請求。一旦連接建立,“事件”便會自動被推送到客戶端。服務器端SSE通過“事件流(Event Stream)”的格式產生並推送事件。事件流對應的MIME類型為“text/event-stream”,包含四個字段:event、data、id和retry。event表示事件類型,data表示消息內容,id用於設置客戶端EventSource對象的“last event ID string”內部屬性,retry指定了重新連接的時間。

node代碼示例:

前端部分

var evtSource = new EventSource("http://localhost:3000");
let eventList = document.getElementsByTagName('body')[0]
// evtSource.onmessage = function(e) {
//     console.log(1111,e);
//     var newElement = document.createElement("li");
//     const eventList = document.getElementsByTagName('body')[0]
//     // console.log(eventList);
//     newElement.innerHTML = "message: " + e.data;
//     eventList.appendChild(newElement);
// }

evtSource.addEventListener("ping", function(e) {
    console.log(2222,e);    
    var newElement = document.createElement("li");
    let eventList = document.getElementsByTagName('body')[0]
    var obj = JSON.parse(e.data);
    newElement.innerHTML = "ping at " + obj.date;
    eventList.appendChild(newElement);
    
}, false);
  
evtSource.addEventListener("error",function(e){
    console.log("服務器發送給客戶端的數據為:" + e.data);
});

//只要和服務器連接,就會觸發open事件
evtSource.addEventListener("open",function(){
    console.log("和服務器建立連接");
 });

 //處理服務器響應報文中的load事件
 evtSource.addEventListener("load",function(e){
     console.log("服務器發送給客戶端的數據為:" + e.data);
 });

  服務端部分

const http = require('http')

http.createServer((req, res) => {
    res.writeHead(200, {
        'Content-Type' : 'text/event-stream',
        'Access-Control-Allow-Origin':'*'
    })
    let i = 0;
    const timer = setInterval(()=>{
        const date = {date:new Date()}
        var content = 'event: ping\n'+"data:"+JSON.stringify(date)+"" + "\n\n";
        res.write(content);
    },1000)

    res.connection.on("close", function(){
        res.end();
        clearInterval(timer);
        console.log("Client closed connection. Aborting.");
        });

}).listen(3000)
console.log('server is run http://localhost:3000');

  java的示例

protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //媒體類型為 text/event-stream
        response.setContentType("text/event-stream");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();

        //響應報文格式為:
        //data:Hello World
        //event:load
        //id:140312
        //換行符(/r/n)

        out.println("data:Hello World");
        out.println("event:load");
        out.println("id:140312");
        out.println();
        out.flush();
        out.close();
}

  SSE相較於輪詢具有較好的實時性,使用方法也非常簡便。然而SSE只支持服務器到客戶端單向的事件推送,而且所有版本的IE(包括到目前為止的Microsoft Edge)都不支持SSE。如果需要強行支持IE和部分移動端瀏覽器,可以嘗試EventSource Polyfill(本質上仍然是輪詢)

 

參考文章:

https://developer.mozilla.org/zh-CN/docs/Server-sent_events/Using_server-sent_events

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM