国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

服務(wù)端事件EventSource揭秘

sf190404 / 3046人閱讀

摘要:不過(guò)永久幀的技術(shù)會(huì)導(dǎo)致主頁(yè)面的加載條始終處于狀態(tài),體驗(yàn)很差。同時(shí),規(guī)范允許服務(wù)端指定自定義事件,客戶(hù)端偵聽(tīng)該事件即可。

服務(wù)端推

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

客戶(hù)端長(zhǎng)輪訓(xùn)

websocket雙向連接

iframe永久幀

長(zhǎng)輪訓(xùn)雖然可以避免短輪訓(xùn)造成的服務(wù)端過(guò)載,但在服務(wù)端返回?cái)?shù)據(jù)后仍需要客戶(hù)端主動(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ì)客戶(hù)端開(kāi)發(fā)人員而言非常簡(jiǎn)單,兼容性上出了IE系的瀏覽器(IE、Edge)外其他都良好;對(duì)于服務(wù)端,它可以兼容老的瀏覽器,無(wú)需upgrade為其他協(xié)議,在簡(jiǎn)單的服務(wù)端推送的場(chǎng)景下可以滿(mǎn)足需求。在瀏覽器與服務(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ù)端指定自定義事件,客戶(hù)端偵聽(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: customMessagen;

data指定具體的消息體,可以是對(duì)象或者字符串,如data: JSON.stringify(jsonObj) ,在消息體后面有兩個(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: 369n),eventSource.lastEventId == 369。該字段使用場(chǎng)景不大;

retry設(shè)置當(dāng)前http連接失敗后,重新連接的間隔。EventSource規(guī)范規(guī)定,客戶(hù)端在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ù)端做心跳保活,否則客戶(hù)端在連接超時(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 }
data: ${ JSON.stringify(data) }

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

`);
}
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è)面代碼






    
hello world

參考資料

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

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/89422.html

相關(guān)文章

  • SSE eventSource簡(jiǎn)介

    eventSource簡(jiǎn)單介紹 eventSource是用來(lái)解決web上服務(wù)器端向客戶(hù)端推送消息的問(wèn)題的。不同于ajax輪詢(xún)的復(fù)雜和websocket的資源占用過(guò)大,eventSource(sse)是一個(gè)輕量級(jí)的,易使用的消息推送api 如何使用 客戶(hù)端代碼 Document (function() { var sour...

    lixiang 評(píng)論0 收藏0
  • H5數(shù)據(jù)推送

    摘要:本文則試著和讀者一起對(duì)這個(gè)數(shù)據(jù)推送的需求進(jìn)行技術(shù)方案的探究。數(shù)據(jù)推送有兩種替代方案無(wú)更新方案和數(shù)據(jù)拉取方案。數(shù)據(jù)拉取和數(shù)據(jù)推送的功能目標(biāo)是一致的讓用戶(hù)看到最新的數(shù)據(jù)。但數(shù)據(jù)推送有一些優(yōu)勢(shì),即更低的延遲。 前言 眾所周知,AJAX的出現(xiàn)是前端快速發(fā)展的一個(gè)標(biāo)志,同時(shí)也是前后端得以分離的重要基礎(chǔ)。作為一個(gè)C/S網(wǎng)絡(luò)的web系統(tǒng),網(wǎng)絡(luò)通信在發(fā)揮著舉足輕重的作用。大部分的場(chǎng)景下,我們是主動(dòng)觸發(fā)...

    劉德剛 評(píng)論0 收藏0
  • H5數(shù)據(jù)推送

    摘要:本文則試著和讀者一起對(duì)這個(gè)數(shù)據(jù)推送的需求進(jìn)行技術(shù)方案的探究。數(shù)據(jù)推送有兩種替代方案無(wú)更新方案和數(shù)據(jù)拉取方案。數(shù)據(jù)拉取和數(shù)據(jù)推送的功能目標(biāo)是一致的讓用戶(hù)看到最新的數(shù)據(jù)。但數(shù)據(jù)推送有一些優(yōu)勢(shì),即更低的延遲。 前言 眾所周知,AJAX的出現(xiàn)是前端快速發(fā)展的一個(gè)標(biāo)志,同時(shí)也是前后端得以分離的重要基礎(chǔ)。作為一個(gè)C/S網(wǎng)絡(luò)的web系統(tǒng),網(wǎng)絡(luò)通信在發(fā)揮著舉足輕重的作用。大部分的場(chǎng)景下,我們是主動(dòng)觸發(fā)...

    nidaye 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

sf190404

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<