公交车上荫蒂添的好舒服的电影-公用玩物(np双xing总受)-公用小荡货芊芊-公与妇仑乱hd-攻把受做哭边走边肉楼梯play-古装一级淫片a免费播放口

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

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

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

一、EventSource的基本概念

EventSource是HTML5中的一種新的API,用來(lái)實(shí)現(xiàn)服務(wù)器端向客戶端推送事件。相比于常規(guī)的輪詢方式,EventSource可以實(shí)現(xiàn)更加高效、低延遲的數(shù)據(jù)傳輸。

它的基本使用方式是,首先在客戶端創(chuàng)建一個(gè)EventSource對(duì)象,然后向指定的服務(wù)器端URL發(fā)送一個(gè)HTTP請(qǐng)求。此時(shí),服務(wù)器端需要支持EventStream格式,即Content-Type為text/event-stream。一旦客戶端收到了這個(gè)請(qǐng)求的響應(yīng),它就會(huì)開(kāi)始監(jiān)聽(tīng)服務(wù)器端的事件,并將事件流動(dòng)態(tài)地展現(xiàn)在網(wǎng)頁(yè)中。

EventSource主要有以下幾個(gè)特性:

1、實(shí)時(shí)性。EventSource能夠?qū)崿F(xiàn)實(shí)時(shí)地?cái)?shù)據(jù)傳輸,可以在服務(wù)器端有新事件時(shí)立即向客戶端推送,并自動(dòng)進(jìn)行展示。

2、低延遲。由于EventSource采用長(zhǎng)連接的方式進(jìn)行傳輸,相比于普通的輪詢方式,它能夠更加高效地傳輸數(shù)據(jù)。

3、易用性。EventSource是一種非常易用的API,只需要在客戶端創(chuàng)建一個(gè)EventSource對(duì)象,指定服務(wù)器端的URL,即可進(jìn)行監(jiān)聽(tīng)并展示事件。

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

二、EventSource的具體應(yīng)用場(chǎng)景

EventSource主要用來(lái)實(shí)現(xiàn)服務(wù)器端向客戶端實(shí)時(shí)推送事件,它在Web應(yīng)用中的應(yīng)用場(chǎng)景非常廣泛。下面列舉幾個(gè)具體的應(yīng)用場(chǎng)景:

1、即時(shí)聊天。在即時(shí)聊天應(yīng)用中,EventSource可以實(shí)現(xiàn)實(shí)時(shí)向客戶端推送新消息,從而保證聊天效果的實(shí)時(shí)性和流暢性。

2、數(shù)據(jù)監(jiān)控。在數(shù)據(jù)監(jiān)控應(yīng)用中,EventSource可以實(shí)時(shí)向客戶端推送最新的監(jiān)控?cái)?shù)據(jù),從而讓用戶及時(shí)掌握系統(tǒng)狀態(tài)。

3、消息提示。在消息提示應(yīng)用中,EventSource可以實(shí)時(shí)向客戶端推送最新的通知信息,讓用戶不會(huì)錯(cuò)過(guò)任何重要消息。

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

三、EventSource的優(yōu)缺點(diǎn)

EventSource作為一種新的Web API,具備自身的優(yōu)缺點(diǎn):

1、優(yōu)點(diǎn)

(1)實(shí)時(shí)展示:EventSource能夠?qū)崿F(xiàn)實(shí)時(shí)展示服務(wù)器端的事件,相比于常規(guī)的輪詢方式,它能夠更加高效、低延遲的展示數(shù)據(jù)。

(2)易用性:EventSource是一種非常易用的API,只需要在客戶端創(chuàng)建一個(gè)EventSource對(duì)象,指定服務(wù)器端的URL,即可進(jìn)行監(jiān)聽(tīng)并展示事件。

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

(4)網(wǎng)絡(luò)帶寬節(jié)?。篍ventSource采用長(zhǎng)連接的方式進(jìn)行數(shù)據(jù)傳輸,相比于普通的輪詢方式,能夠節(jié)省大量的網(wǎng)絡(luò)帶寬。

2、缺點(diǎn)

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

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

(3)不支持重連:如果網(wǎng)絡(luò)連接不穩(wěn)定,或者服務(wù)器端關(guān)閉EventStream連接,客戶端需要重新連接才能繼續(xù)監(jiān)聽(tīng)事件。

四、如何使用EventSource

使用EventSource也比較簡(jiǎn)單,只需要?jiǎng)?chuàng)建一個(gè)EventSource對(duì)象并指定服務(wù)器端的URL即可。下面是一個(gè)簡(jiǎn)單的使用示例:

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

eventSource.onmessage = function(event) {

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

};

在這個(gè)示例中,創(chuàng)建了一個(gè)EventSource對(duì)象,并指定服務(wù)器端的URL為"/events"。同時(shí),還注冊(cè)了一個(gè)onmessage事件回調(diào)函數(shù),在每次收到服務(wù)器端推送的事件時(shí),會(huì)打印出事件數(shù)據(jù)。

在服務(wù)器端,需要確保能夠接收和處理EventStream格式的HTTP請(qǐng)求。下面是一個(gè)簡(jiǎn)單的Node.js的Express應(yīng)用示例:

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!');

});

在這個(gè)示例中,創(chuàng)建了一個(gè)Express應(yīng)用,并通過(guò)路由"/events"來(lái)處理EventSource請(qǐng)求。其中,將響應(yīng)的Content-Type設(shè)置為text/event-stream,表示返回的數(shù)據(jù)格式為EventStream。同時(shí),通過(guò)設(shè)置Cache-Control和Connection實(shí)現(xiàn)長(zhǎng)連接的功能。在每秒鐘向客戶端推送一個(gè)帶時(shí)間戳的事件。

五、總結(jié)

本文主要介紹了EventSource的基本概念、具體應(yīng)用場(chǎng)景、優(yōu)缺點(diǎn)以及使用方法。盡管EventSource在某些場(chǎng)景下可能存在一定的局限性,但它仍然是一種非常強(qiáng)大的前端Web API,能夠?qū)崿F(xiàn)實(shí)時(shí)、低延遲的數(shù)據(jù)傳輸,具備很好的兼容性和易用性。在實(shí)際應(yīng)用中,需要針對(duì)具體的場(chǎng)景進(jìn)行合理使用,從而發(fā)揮最大的效果。


該文章在 2024/6/15 11:42:55 編輯過(guò)

全部評(píng)論1

admin
2024年6月15日 10:55

服務(wù)端推

服務(wù)端推,指的是由服務(wù)器主動(dòng)的向客戶端發(fā)送消息(響應(yīng))。在應(yīng)用層的HTTP協(xié)議實(shí)現(xiàn)中,“請(qǐng)求-響應(yīng)”是一個(gè)round trip,它的起點(diǎn)來(lái)自客戶端,因此在應(yīng)用層之上無(wú)法實(shí)現(xiàn)簡(jiǎn)易的服務(wù)端推功能。當(dāng)前解決服務(wù)端推送的方案有這幾個(gè):

1、客戶端長(zhǎng)輪詢

2、websocket雙向連

3、iframe永久幀

長(zhǎng)輪訓(xùn)雖然可以避免短輪訓(xùn)造成的服務(wù)端過(guò)載,但在服務(wù)端返回?cái)?shù)據(jù)后仍需要客戶端主動(dòng)發(fā)起下一個(gè)長(zhǎng)輪訓(xùn)請(qǐng)求,等待服務(wù)端響應(yīng),這樣仍需要底層的連接建立而且服務(wù)端處理邏輯需要相應(yīng)處理,不符合邏輯上的流程簡(jiǎn)單的服務(wù)端推送;

websocket連接相對(duì)而言功能最強(qiáng)大,但是它對(duì)服務(wù)器的版本有要求,在可以使用websocket協(xié)議的服務(wù)器上盡量采用此種方式;

iframe永久幀則是在在頁(yè)面嵌入一個(gè)專(zhuān)用來(lái)接受數(shù)據(jù)的iframe頁(yè)面,該頁(yè)面由服務(wù)器輸出相關(guān)信息,如,服務(wù)器不停的向iframe中寫(xiě)入類(lèi)似的script標(biāo)簽和數(shù)據(jù),實(shí)現(xiàn)另一種形式的服務(wù)端推送。不過(guò)永久幀的技術(shù)會(huì)導(dǎo)致主頁(yè)面的加載條始終處于“l(fā)oading”狀態(tài),體驗(yàn)很差。

HTML5規(guī)范中提供了服務(wù)端事件EventSource,瀏覽器在實(shí)現(xiàn)了該規(guī)范的前提下創(chuàng)建一個(gè)EventSource連接后,便可收到服務(wù)端的發(fā)送的消息,這些消息需要遵循一定的格式,對(duì)于前端開(kāi)發(fā)人員而言,只需在瀏覽器中偵聽(tīng)對(duì)應(yīng)的事件皆可。

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

EventSource規(guī)范簡(jiǎn)析

瀏覽器端

瀏覽器端,需要?jiǎng)?chuàng)建一個(gè)EventSource對(duì)象,并且傳入一個(gè)服務(wù)端的接口URI作為參數(shù)。

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

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

默認(rèn)EventSource對(duì)象通過(guò)偵聽(tīng)“message”事件獲取服務(wù)端傳來(lái)的消息,“open”事件則在http連接建立后觸發(fā),”error“事件會(huì)在通信錯(cuò)誤(連接中斷、服務(wù)端返回?cái)?shù)據(jù)失敗)的情況下觸發(fā)。同時(shí),EventSource規(guī)范允許服務(wù)端指定自定義事件,客戶端偵聽(tīng)該事件即可。

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

    console.log(e.data);

});

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

    console.log(e);

})

服務(wù)端

事件流的對(duì)應(yīng)MIME格式為text/event-stream,而且其基于HTTP長(zhǎng)連接。針對(duì)HTTP1.1規(guī)范默認(rèn)采用長(zhǎng)連接,針對(duì)HTTP1.0的服務(wù)器需要特殊設(shè)置。

服務(wù)端返回?cái)?shù)據(jù)需要特殊的格式,它分為四種消息類(lèi)型:

event, data, id, retry

其中,event指定自定義消息的名稱(chēng),如event: customMessage\n;

data指定具體的消息體,可以是對(duì)象或者字符串,如data: JSON.stringify(jsonObj)\n\n,在消息體后面有兩個(gè)換行符\n,代表當(dāng)前消息體發(fā)送完畢,一個(gè)換行符標(biāo)識(shí)當(dāng)前消息并未結(jié)束,瀏覽器需要等待后面數(shù)據(jù)的到來(lái)后再觸發(fā)事件;

id為當(dāng)前消息的標(biāo)識(shí)符,可以不設(shè)置。一旦設(shè)置則在瀏覽器端的eventSource對(duì)象中就會(huì)有體現(xiàn)(假設(shè)服務(wù)端返回id: 369\n),eventSource.lastEventId == 369。該字段使用場(chǎng)景不大;

retry設(shè)置當(dāng)前http連接失敗后,重新連接的間隔。EventSource規(guī)范規(guī)定,客戶端在http連接失敗后默認(rèn)進(jìn)行重新連接,重連間隔為3s,通過(guò)設(shè)置retry字段可指定重連間隔;

每個(gè)字段都有名稱(chēng),緊接著有個(gè)”:“。當(dāng)出現(xiàn)一個(gè)沒(méi)有名稱(chēng)的字段而只有”:“時(shí),這就會(huì)被服務(wù)端理解為”注釋“,并不會(huì)被發(fā)送至瀏覽器端,如: commision。

由于EventSource是基于HTTP連接之上的,因此在一段沒(méi)有數(shù)據(jù)的時(shí)期會(huì)出現(xiàn)超時(shí)問(wèn)題。服務(wù)器默認(rèn)HTTP超時(shí)時(shí)間為2分鐘,在node端可以通過(guò)response.connection.setTimeou(0)設(shè)置為默認(rèn)的2min超時(shí), 因此需要服務(wù)端做心跳?;?,否則客戶端在連接超時(shí)的情況下出現(xiàn)net::ERR_INCOMPLETE_CHUNKED_ENCODING錯(cuò)誤。通過(guò)閱讀相關(guān)規(guī)范,發(fā)現(xiàn)注釋行可以用來(lái)防止連接超時(shí),服務(wù)器可以定期發(fā)送一條消息注釋行,以保持連接不斷。

下面提供koa的服務(wù)端代碼:

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的返回值必須是一個(gè)Stream(Readable),這是由于koa的特殊性造成的。如果context.body不是Stream是一個(gè)字符串或者Buffer實(shí)例,會(huì)直接在node原生中調(diào)用res.end(buffer),結(jié)束了HTTP響應(yīng):

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

因此造成了服務(wù)端事件流無(wú)法正確響應(yīng)。而返回Stream類(lèi)型的方式有幾種,如通過(guò)擴(kuò)展stream模塊的Readable可讀流返回或者直接采用PassThrough流返回,亦可通過(guò)through2模塊或者Transform對(duì)象實(shí)現(xiàn),歸根到底保證可以從該stream對(duì)象中pipe出數(shù)據(jù)至http.ServerResponse對(duì)象中。

附頁(yè)面代碼

<!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>

參考資料

使用服務(wù)器發(fā)送事件 EventSource超時(shí)


該評(píng)論在 2024/6/15 11:50:39 編輯過(guò)
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專(zhuān)業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車(chē)隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類(lèi)企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷(xiāo)售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 91精品国产三级a在线 | 国产亚洲一区在线 | 极品熟女少妇av免费久久自慰 | 东京热无码中文字幕av专区 | av天堂精品 | 国产精品无码亚洲精品蜜桃传媒 | 精品国产91无码大片在线观看 | 国产一区二区三区视频在线观看 | 精品国产四虎影视 | 国产a级一级久久毛片 | 99久久久无码国产精品66 | 国产精品毛片一区二区三区 | 国产一区二区三区乱码 | 精品视频麻豆网站 | 国产高潮好爽好大好紧受不了了 | 国产成人精品免费一区 | 国产精品亚洲一区 | 国产精品白浆无码流出在线观看 | 国产午夜福利最新在线观看 | 精品久久久久久天美传媒 | 精品美女久久久久久久 | 99久久久久久宅男 | 911午夜福利精品 | 丰满的岳乱妇久久久 | 国产精品一线二线三线区别解析 | 国产精品成人一区二区三区视 | 成人欧美一区二区三区在线观看 | 精品偷拍无码不卡av | 国产一区二区日韩一区二区 | 精品高清国产一区二区三区四区 | 国产精品亚洲精品日韩己满 | 国产成人av在线免播放观看 | 国产精品福利在线观看无码卡一 | av网址国产在线看 | 国产91对白在线 | 果冻传媒aⅴ毛片无码蜜桃 果冻传媒app在线播放 | 国精产品一区二区三区糖心269 | 国产精品亚洲一区二区在线观 | 动漫精品一区二区无码 | 国产精品亚洲美女久久久 | 加勒比在线精品视频 |