狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

【JavaScript】WEB客戶端與服務端通訊事件EventSource揭秘

admin
2024年6月15日 10:54 本文熱度 1035

一、EventSource的基本概念

EventSource是HTML5中的一種新的API,用來實現服務器端向客戶端推送事件。相比于常規的輪詢方式,EventSource可以實現更加高效、低延遲的數據傳輸。

它的基本使用方式是,首先在客戶端創建一個EventSource對象,然后向指定的服務器端URL發送一個HTTP請求。此時,服務器端需要支持EventStream格式,即Content-Type為text/event-stream。一旦客戶端收到了這個請求的響應,它就會開始監聽服務器端的事件,并將事件流動態地展現在網頁中。

EventSource主要有以下幾個特性:

1、實時性。EventSource能夠實現實時地數據傳輸,可以在服務器端有新事件時立即向客戶端推送,并自動進行展示。

2、低延遲。由于EventSource采用長連接的方式進行傳輸,相比于普通的輪詢方式,它能夠更加高效地傳輸數據。

3、易用性。EventSource是一種非常易用的API,只需要在客戶端創建一個EventSource對象,指定服務器端的URL,即可進行監聽并展示事件。

4、兼容性。EventSource能夠同時兼容WebSocket和長輪詢等方式,具備很好的兼容性,可以在各種不同的場景下使用。

二、EventSource的具體應用場景

EventSource主要用來實現服務器端向客戶端實時推送事件,它在Web應用中的應用場景非常廣泛。下面列舉幾個具體的應用場景:

1、即時聊天。在即時聊天應用中,EventSource可以實現實時向客戶端推送新消息,從而保證聊天效果的實時性和流暢性。

2、數據監控。在數據監控應用中,EventSource可以實時向客戶端推送最新的監控數據,從而讓用戶及時掌握系統狀態。

3、消息提示。在消息提示應用中,EventSource可以實時向客戶端推送最新的通知信息,讓用戶不會錯過任何重要消息。

4、廣告推送。在廣告推送應用中,EventSource可以實時向客戶端推送最新的廣告信息,從而提高廣告的投放效果。

三、EventSource的優缺點

EventSource作為一種新的Web API,具備自身的優缺點:

1、優點

(1)實時展示:EventSource能夠實現實時展示服務器端的事件,相比于常規的輪詢方式,它能夠更加高效、低延遲的展示數據。

(2)易用性:EventSource是一種非常易用的API,只需要在客戶端創建一個EventSource對象,指定服務器端的URL,即可進行監聽并展示事件。

(3)兼容性良好:EventSource能夠同時兼容WebSocket和長輪詢等方式,具備很好的兼容性,可以在各種不同的場景下使用。

(4)網絡帶寬節省:EventSource采用長連接的方式進行數據傳輸,相比于普通的輪詢方式,能夠節省大量的網絡帶寬。

2、缺點

(1)一次性消息:EventSource只能一次性地向客戶端推送一條消息,而不能像WebSocket那樣實現雙向通訊。

(2)不支持二進制數據傳輸:EventSource只能傳輸文本數據,不能傳輸二進制數據,這在某些場景下可能存在一定的局限性。

(3)不支持重連:如果網絡連接不穩定,或者服務器端關閉EventStream連接,客戶端需要重新連接才能繼續監聽事件。

四、如何使用EventSource

使用EventSource也比較簡單,只需要創建一個EventSource對象并指定服務器端的URL即可。下面是一個簡單的使用示例:

var eventSource = new EventSource("/events");

eventSource.onmessage = function(event) {

  console.log("Received event: " + event.data);

};

在這個示例中,創建了一個EventSource對象,并指定服務器端的URL為"/events"。同時,還注冊了一個onmessage事件回調函數,在每次收到服務器端推送的事件時,會打印出事件數據。

在服務器端,需要確保能夠接收和處理EventStream格式的HTTP請求。下面是一個簡單的Node.js的Express應用示例:

const express = require('express');

const app = express();


app.get('/events', function(req, res) {

  res.set({

    'Content-Type': 'text/event-stream',

    'Cache-Control': 'no-cache',

    'Connection': 'keep-alive'

  });


  setInterval(function() {

    res.write('data: ' + new Date().toISOString() + '\n\n');

  }, 1000);

});


app.listen(3000, function() {

  console.log('Example app listening on port 3000!');

});

在這個示例中,創建了一個Express應用,并通過路由"/events"來處理EventSource請求。其中,將響應的Content-Type設置為text/event-stream,表示返回的數據格式為EventStream。同時,通過設置Cache-Control和Connection實現長連接的功能。在每秒鐘向客戶端推送一個帶時間戳的事件。

五、總結

本文主要介紹了EventSource的基本概念、具體應用場景、優缺點以及使用方法。盡管EventSource在某些場景下可能存在一定的局限性,但它仍然是一種非常強大的前端Web API,能夠實現實時、低延遲的數據傳輸,具備很好的兼容性和易用性。在實際應用中,需要針對具體的場景進行合理使用,從而發揮最大的效果。


該文章在 2024/6/15 11:42:55 編輯過

全部評論1

admin
2024年6月15日 10:55

服務端推

服務端推,指的是由服務器主動的向客戶端發送消息(響應)。在應用層的HTTP協議實現中,“請求-響應”是一個round trip,它的起點來自客戶端,因此在應用層之上無法實現簡易的服務端推功能。當前解決服務端推送的方案有這幾個:

1、客戶端長輪詢

2、websocket雙向連

3、iframe永久幀

長輪訓雖然可以避免短輪訓造成的服務端過載,但在服務端返回數據后仍需要客戶端主動發起下一個長輪訓請求,等待服務端響應,這樣仍需要底層的連接建立而且服務端處理邏輯需要相應處理,不符合邏輯上的流程簡單的服務端推送;

websocket連接相對而言功能最強大,但是它對服務器的版本有要求,在可以使用websocket協議的服務器上盡量采用此種方式;

iframe永久幀則是在在頁面嵌入一個專用來接受數據的iframe頁面,該頁面由服務器輸出相關信息,如,服務器不停的向iframe中寫入類似的script標簽和數據,實現另一種形式的服務端推送。不過永久幀的技術會導致主頁面的加載條始終處于“loading”狀態,體驗很差。

HTML5規范中提供了服務端事件EventSource,瀏覽器在實現了該規范的前提下創建一個EventSource連接后,便可收到服務端的發送的消息,這些消息需要遵循一定的格式,對于前端開發人員而言,只需在瀏覽器中偵聽對應的事件皆可。

相比較上文中提到的3中實現方式,EventSource流的實現方式對客戶端開發人員而言非常簡單,兼容性上出了IE系的瀏覽器(IE、Edge)外其他都良好;對于服務端,它可以兼容老的瀏覽器,無需upgrade為其他協議,在簡單的服務端推送的場景下可以滿足需求。在瀏覽器與服務端需要強交互的場景下,websocket仍是不二的選擇。

EventSource規范簡析

瀏覽器端

瀏覽器端,需要創建一個EventSource對象,并且傳入一個服務端的接口URI作為參數。

var evtSource = new EventSource('http://localhost:9111/es');

其中,'http://localhost:9111/es'為服務端吐出數據的接口。目前,EventSource在大多數瀏覽器端不支持 跨域,因此它不是一種跨域的解決方案。

默認EventSource對象通過偵聽“message”事件獲取服務端傳來的消息,“open”事件則在http連接建立后觸發,”error“事件會在通信錯誤(連接中斷、服務端返回數據失敗)的情況下觸發。同時,EventSource規范允許服務端指定自定義事件,客戶端偵聽該事件即可。

evtSource.addEventListener('message',function(e){

    console.log(e.data);

});

evtSource.addEventListener('error',function(e){

    console.log(e);

})

服務端

事件流的對應MIME格式為text/event-stream,而且其基于HTTP長連接。針對HTTP1.1規范默認采用長連接,針對HTTP1.0的服務器需要特殊設置。

服務端返回數據需要特殊的格式,它分為四種消息類型:

event, data, id, retry

其中,event指定自定義消息的名稱,如event: customMessage\n;

data指定具體的消息體,可以是對象或者字符串,如data: JSON.stringify(jsonObj)\n\n,在消息體后面有兩個換行符\n,代表當前消息體發送完畢,一個換行符標識當前消息并未結束,瀏覽器需要等待后面數據的到來后再觸發事件;

id為當前消息的標識符,可以不設置。一旦設置則在瀏覽器端的eventSource對象中就會有體現(假設服務端返回id: 369\n),eventSource.lastEventId == 369。該字段使用場景不大;

retry設置當前http連接失敗后,重新連接的間隔。EventSource規范規定,客戶端在http連接失敗后默認進行重新連接,重連間隔為3s,通過設置retry字段可指定重連間隔;

每個字段都有名稱,緊接著有個”:“。當出現一個沒有名稱的字段而只有”:“時,這就會被服務端理解為”注釋“,并不會被發送至瀏覽器端,如: commision

由于EventSource是基于HTTP連接之上的,因此在一段沒有數據的時期會出現超時問題。服務器默認HTTP超時時間為2分鐘,在node端可以通過response.connection.setTimeou(0)設置為默認的2min超時, 因此需要服務端做心跳保活,否則客戶端在連接超時的情況下出現net::ERR_INCOMPLETE_CHUNKED_ENCODING錯誤。通過閱讀相關規范,發現注釋行可以用來防止連接超時,服務器可以定期發送一條消息注釋行,以保持連接不斷。

下面提供koa的服務端代碼:

var fs = require('fs');

var path = require('path');

var PassThrough = require('stream').PassThrough;

var Readable = require('stream').Readable;

var koa = require('koa');

var Router = require('koa-router');

var app = new koa();

var router = new Router();


function RR(){

    Readable.call(this,arguments);

}

RR.prototype = new Readable();

RR.prototype._read = function(data){

}


router.get('/',function(ctx,next){

    ctx.set('content-type','text/html');

    ctx.body = fs.readFileSync(path.join(process.cwd(),'eventServer.html'));

});


const sse = (stream,event, data) => {

    return stream.push(`event:${ event }\ndata: ${ JSON.stringify(data) }\n\n`)

//    return stream.write(`event:${ event }\ndata: ${ JSON.stringify(data) }\n\n`);

}

router.get('/es',function(ctx,next){

    var stream = new RR()//PassThrough();

    ctx.set({

        'Content-Type':'text/event-stream',

        'Cache-Control':'no-cache',

        Connection: 'keep-alive'

    });

    sse(stream,'test',{a: "yango",b: "tango"});

    ctx.body = stream;

    setInterval(()=>{

        sse(stream,'test',{a: "yango",b: Date.now()});

    },3000); 

});


app.use(router.routes());

app.listen(9111,function(){

    console.log('listening port 9111');

});

此處需要注意的是koa-router的返回值必須是一個Stream(Readable),這是由于koa的特殊性造成的。如果context.body不是Stream是一個字符串或者Buffer實例,會直接在node原生中調用res.end(buffer),結束了HTTP響應:

koa lib/application.js


// responses

if (Buffer.isBuffer(body)) return res.end(body);

if ('string' == typeof body) return res.end(body);

if (body instanceof Stream) return body.pipe(res);

因此造成了服務端事件流無法正確響應。而返回Stream類型的方式有幾種,如通過擴展stream模塊的Readable可讀流返回或者直接采用PassThrough流返回,亦可通過through2模塊或者Transform對象實現,歸根到底保證可以從該stream對象中pipe出數據至http.ServerResponse對象中。

附頁面代碼

<!DOCTYPE html>

<html>

<head>

</head>

<body>

    <div>

        hello world

    </div>

    <p id="info"></p>

    <script>

        var infoShow = document.querySelector('#info');

        var se = new EventSource('http://localhost:9111/es');

        se.addEventListener('test',function(e){

            infoShow.textContent += e.data+'\n';

        });

        se.addEventListener('error',function(e){

            console.log(e);

        })

    </script>

</body>

</html>

參考資料

使用服務器發送事件 EventSource超時


該評論在 2024/6/15 11:50:39 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved