JS中SSE (Server-Sent event)服務(wù)器向?yàn)g覽器推送信息

SSE

服務(wù)器向?yàn)g覽器推送信息凡人,除了 WebSocket,還有一種方法:Server-Sent Events(以下簡(jiǎn)稱(chēng) SSE)叹阔。本文介紹它的用法挠轴。

SSE 的本質(zhì)

嚴(yán)格地說(shuō),HTTP 協(xié)議無(wú)法做到服務(wù)器主動(dòng)推送信息耳幢。但是忠荞,有一種變通方法,就是服務(wù)器向客戶端聲明帅掘,接下來(lái)要發(fā)送的是流信息(streaming)。

也就是說(shuō)堂油,發(fā)送的不是一次性的數(shù)據(jù)包修档,而是一個(gè)數(shù)據(jù)流,會(huì)連續(xù)不斷地發(fā)送過(guò)來(lái)府框。這時(shí)吱窝,客戶端不會(huì)關(guān)閉連接,會(huì)一直等著服務(wù)器發(fā)過(guò)來(lái)的新的數(shù)據(jù)流,視頻播放就是這樣的例子院峡。本質(zhì)上兴使,這種通信就是以流信息的方式,完成一次用時(shí)很長(zhǎng)的下載照激。

SSE 就是利用這種機(jī)制发魄,使用流信息向?yàn)g覽器推送信息。它基于 HTTP 協(xié)議俩垃,目前除了 IE/Edge励幼,其他瀏覽器都支持。

SSE 的特點(diǎn)

SSE 與 WebSocket 作用相似口柳,都是建立瀏覽器與服務(wù)器之間的通信渠道苹粟,然后服務(wù)器向?yàn)g覽器推送信息。

總體來(lái)說(shuō)跃闹,WebSocket 更強(qiáng)大和靈活嵌削。因?yàn)樗侨p工通道,可以雙向通信望艺;SSE 是單向通道苛秕,只能服務(wù)器向?yàn)g覽器發(fā)送,因?yàn)榱餍畔⒈举|(zhì)上就是下載荣茫。如果瀏覽器向服務(wù)器發(fā)送信息想帅,就變成了另一次 HTTP 請(qǐng)求。

但是啡莉,SSE 也有自己的優(yōu)點(diǎn)港准。

SSE 使用 HTTP 協(xié)議,現(xiàn)有的服務(wù)器軟件都支持咧欣。WebSocket 是一個(gè)獨(dú)立協(xié)議浅缸。
SSE 屬于輕量級(jí),使用簡(jiǎn)單魄咕;WebSocket 協(xié)議相對(duì)復(fù)雜衩椒。
SSE 默認(rèn)支持?jǐn)嗑€重連,WebSocket 需要自己實(shí)現(xiàn)哮兰。
SSE 一般只用來(lái)傳送文本毛萌,二進(jìn)制數(shù)據(jù)需要編碼后傳送,WebSocket 默認(rèn)支持傳送二進(jìn)制數(shù)據(jù)喝滞。
SSE 支持自定義發(fā)送的消息類(lèi)型阁将。
因此,兩者各有特點(diǎn)右遭,適合不同的場(chǎng)合做盅。

三缤削、客戶端 API

3.1 EventSource 對(duì)象

SSE 的客戶端 API 部署在EventSource對(duì)象上。下面的代碼可以檢測(cè)瀏覽器是否支持 SSE吹榴。

if ('EventSource' in window) {
// ...
}
使用 SSE 時(shí)亭敢,瀏覽器首先生成一個(gè)EventSource實(shí)例,向服務(wù)器發(fā)起連接图筹。

var source = new EventSource(url);
上面的url可以與當(dāng)前網(wǎng)址同域帅刀,也可以跨域⌒龀猓跨域時(shí)劝篷,可以指定第二個(gè)參數(shù),打開(kāi)withCredentials屬性民宿,表示是否一起發(fā)送 Cookie娇妓。

var source = new EventSource(url, { withCredentials: true });
EventSource實(shí)例的readyState屬性,表明連接的當(dāng)前狀態(tài)活鹰。該屬性只讀哈恰,可以取以下值。

0:相當(dāng)于常量EventSource.CONNECTING志群,表示連接還未建立着绷,或者斷線正在重連斥难。
1:相當(dāng)于常量EventSource.OPEN脚翘,表示連接已經(jīng)建立缺亮,可以接受數(shù)據(jù)艺挪。
2:相當(dāng)于常量EventSource.CLOSED,表示連接已斷诉濒,且不會(huì)重連汗唱。

3.2 基本用法

連接一旦建立屡拨,就會(huì)觸發(fā)open事件攻冷,可以在onopen屬性定義回調(diào)函數(shù)娃胆。

source.onopen = function (event) {
// ...
};

// 另一種寫(xiě)法
source.addEventListener('open', function (event) {
// ...
}, false);
客戶端收到服務(wù)器發(fā)來(lái)的數(shù)據(jù),就會(huì)觸發(fā)message事件等曼,可以在onmessage屬性的回調(diào)函數(shù)里烦。

source.onmessage = function (event) {
var data = event.data;
// handle message
};

// 另一種寫(xiě)法
source.addEventListener('message', function (event) {
var data = event.data;
// handle message
}, false);
上面代碼中,事件對(duì)象的data屬性就是服務(wù)器端傳回的數(shù)據(jù)(文本格式)禁谦。

如果發(fā)生通信錯(cuò)誤(比如連接中斷)胁黑,就會(huì)觸發(fā)error事件,可以在onerror屬性定義回調(diào)函數(shù)州泊。

source.onerror = function (event) {
// handle error event
};

// 另一種寫(xiě)法
source.addEventListener('error', function (event) {
// handle error event
}, false);
close方法用于關(guān)閉 SSE 連接丧蘸。

source.close();

3.3 自定義事件

默認(rèn)情況下,服務(wù)器發(fā)來(lái)的數(shù)據(jù)拥诡,總是觸發(fā)瀏覽器EventSource實(shí)例的message事件触趴。開(kāi)發(fā)者還可以自定義 SSE 事件,這種情況下渴肉,發(fā)送回來(lái)的數(shù)據(jù)不會(huì)觸發(fā)message事件冗懦。

source.addEventListener('foo', function (event) {
var data = event.data;
// handle message
}, false);
上面代碼中,瀏覽器對(duì) SSE 的foo事件進(jìn)行監(jiān)聽(tīng)仇祭。如何實(shí)現(xiàn)服務(wù)器發(fā)送foo事件披蕉,請(qǐng)看下文。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末没讲,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子礁苗,更是在濱河造成了極大的恐慌爬凑,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件试伙,死亡現(xiàn)場(chǎng)離奇詭異嘁信,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)疏叨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)潘靖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蚤蔓,你說(shuō)我怎么就攤上這事卦溢。” “怎么了秀又?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵单寂,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我涮坐,道長(zhǎng)凄贩,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任袱讹,我火速辦了婚禮疲扎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘捷雕。我一直安慰自己椒丧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布救巷。 她就那樣靜靜地躺著壶熏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪浦译。 梳的紋絲不亂的頭發(fā)上棒假,一...
    開(kāi)封第一講書(shū)人閱讀 51,301評(píng)論 1 301
  • 那天溯职,我揣著相機(jī)與錄音,去河邊找鬼帽哑。 笑死谜酒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的妻枕。 我是一名探鬼主播僻族,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼屡谐!你這毒婦竟也來(lái)了述么?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤愕掏,失蹤者是張志新(化名)和其女友劉穎度秘,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體亭珍,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡敷钾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肄梨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阻荒。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖众羡,靈堂內(nèi)的尸體忽然破棺而出侨赡,到底是詐尸還是另有隱情,我是刑警寧澤粱侣,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布羊壹,位于F島的核電站,受9級(jí)特大地震影響齐婴,放射性物質(zhì)發(fā)生泄漏油猫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一柠偶、第九天 我趴在偏房一處隱蔽的房頂上張望情妖。 院中可真熱鬧,春花似錦诱担、人聲如沸毡证。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)料睛。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間恤煞,已是汗流浹背屎勘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留居扒,地道東北人挑秉。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像苔货,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子立哑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容