服務(wù)端推送技術(shù) Server-sent Events 快速上手

1. 前言

今天項目經(jīng)理交給我一個開發(fā)任務(wù)际乘。如果有人下了訂單就給后臺一個通知坡倔,也就是服務(wù)器推送功能。這個需求不是很復(fù)雜就一個通知功能,如果我用websocket來做還要搞個websocket服務(wù)器致讥,而且還有不少配置。websocket是全雙工通信器赞,單向通信簡直是殺雞用牛刀垢袱。用輪詢吧,浪費(fèi)服務(wù)器資源不說港柜,還不一定實(shí)時请契,訂單處理慢了豈不是怠慢了客戶。有沒有別的選擇呢夏醉?當(dāng)然有爽锥!

2. SSE推送技術(shù)

SSE全稱Server-sent Events,是HTML 5 規(guī)范的一個組成部分畔柔,具體去MDN網(wǎng)站查看相關(guān)文檔氯夷。該規(guī)范十分簡單,主要由兩個部分組成:第一個部分是服務(wù)器端與瀏覽器端之間的通訊協(xié)議靶擦,第二部分則是在瀏覽器端可供 JavaScript 使用的 EventSource 對象腮考。通訊協(xié)議是基于純文本的簡單協(xié)議。服務(wù)器端的響應(yīng)的內(nèi)容類型是“text/event-stream”玄捕。響應(yīng)文本的內(nèi)容可以看成是一個事件流踩蔚,由不同的事件所組成。每個事件由類型和數(shù)據(jù)兩部分組成枚粘,同時每個事件可以有一個可選的標(biāo)識符馅闽。不同事件的內(nèi)容之間通過僅包含回車符和換行符的空行(“\r\n”)來分隔。每個事件的數(shù)據(jù)可能由多行組成馍迄。

如上圖所示福也,每個事件之間通過空行來分隔。每一行都是由鍵值對組成攀圈。如果鍵為空則表示該行為注釋拟杉,會在處理時被忽略。例如第10行量承。
第1行表示一個只包含數(shù)據(jù)的事件搬设。會按照默認(rèn)事件走(message事件)。第3-4代表一個附帶eventID的事件撕捍。第6-8代表一個自定義事件拿穴。第10-14代表一個多行數(shù)據(jù)事件,多行數(shù)據(jù)由換行符鏈接

key定義有以下幾種:

  • data忧风,表示該行包含的是數(shù)據(jù)默色。以 data 開頭的行可以出現(xiàn)多次。所有這些行都是該事件的數(shù)據(jù)狮腿。
  • 類型為 event腿宰,表示該行用來聲明事件的類型呕诉。瀏覽器在收到數(shù)據(jù)時,會產(chǎn)生對應(yīng)類型的事件吃度。默認(rèn)提供三個標(biāo)準(zhǔn)事件(當(dāng)然你可以自定義):
  • id甩挫,表示該行用來聲明事件的標(biāo)識符。服務(wù)器端返回的數(shù)據(jù)中包含了事件的標(biāo)識符椿每,瀏覽器會記錄最近一次接收到的事件的標(biāo)識符伊者。如果與服務(wù)器端的連接中斷,當(dāng)瀏覽器端再次進(jìn)行連接時间护,會通過 HTTP 頭“Last-Event-ID”來聲明最后一次接收到的事件的標(biāo)識符亦渗。服務(wù)器端可以通過瀏覽器端發(fā)送的事件標(biāo)識符來確定從哪個事件開始來繼續(xù)連接。
  • retry汁尺,表示該行用來聲明瀏覽器在連接斷開之后進(jìn)行再次連接之前的等待時間法精。

SSE只適用于高級瀏覽器,但是注意IE不直接支持痴突。IE上的XMLHttpRequest對象不支持獲取部分的響應(yīng)內(nèi)容亿虽,所以不支持。每次總有IE怪不得快被淘汰了苞也。

3. SSE VS Websocket

  • SSE 只能Server到Client單項洛勉,而Websocket是雙向通信。
  • SSE 比 Websocket 輕量如迟。當(dāng)然功能要簡單的多收毫。開發(fā)便利,不牽涉協(xié)議升級問題殷勘。
  • SSE 天然支持?jǐn)嗑€重連

4. Spring Mvc中的SSE

Spring Mvc對SSE進(jìn)行了支持此再。如果你要聲明一個SSE連接。只需要在你的控制器聲明一個如下接口:

必須必須返回SseEmitter對象玲销,SseEmitter對象是Session級別的输拇,如果你要點(diǎn)對點(diǎn)針對每個session要獨(dú)立存儲。如果你是廣播可以公用一個SseEmitter對象贤斜。按照SSE規(guī)范也必須聲明produces為"text/event-stream"策吠。當(dāng)你調(diào)用該接口的時候?qū)⒔⑵餝SE連接。

你可以在另一個線程中調(diào)用SseEmitter的send方法向客戶端發(fā)送事件瘩绒。你也可以在發(fā)送事件后調(diào)用complete方法來關(guān)閉SSE連接猴抹。

5. 客戶端

由于SSE 是HTML5規(guī)范。所以對于APP端必須有HTML才能支持锁荔。并且IE如果要支持需要使用一些兼容開發(fā)包蟀给,比如polyfill庫。客戶端因?yàn)橹唤邮苁录蚤_發(fā)比較簡單:

  • 聲明客戶端連接跋理, 初始化EventSource對象择克。
  • 編寫監(jiān)聽器來監(jiān)聽事件。

6. 總結(jié)

今天介紹了SSE 服務(wù)端推送前普。和長輪訓(xùn)肚邢、comet、websocket相比比較輕量級汁政。在一些需要服務(wù)器實(shí)時推送規(guī)模不大的業(yè)務(wù)場景實(shí)現(xiàn)更簡單點(diǎn)道偷。相信看了本文后你會很快入門缀旁。在實(shí)際開發(fā)中要根據(jù)業(yè)務(wù)對這幾種推送進(jìn)行技術(shù)選型记劈。沒有最好的只有最適合的。只不過SSE對大多數(shù)開發(fā)者來說不夠熟悉并巍。相關(guān)的demo我已經(jīng)上傳到碼云倉庫:

https://gitee.com/felord/sse-push
關(guān)注公眾號:碼農(nóng)小胖哥目木,獲取更多資訊

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市懊渡,隨后出現(xiàn)的幾起案子刽射,更是在濱河造成了極大的恐慌,老刑警劉巖剃执,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件誓禁,死亡現(xiàn)場離奇詭異,居然都是意外死亡肾档,警方通過查閱死者的電腦和手機(jī)摹恰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怒见,“玉大人俗慈,你說我怎么就攤上這事∏菜#” “怎么了闺阱?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長舵变。 經(jīng)常有香客問我酣溃,道長,這世上最難降的妖魔是什么纪隙? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任救拉,我火速辦了婚禮,結(jié)果婚禮上瘫拣,老公的妹妹穿的比我還像新娘亿絮。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布派昧。 她就那樣靜靜地躺著黔姜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蒂萎。 梳的紋絲不亂的頭發(fā)上秆吵,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天,我揣著相機(jī)與錄音五慈,去河邊找鬼纳寂。 笑死,一個胖子當(dāng)著我的面吹牛泻拦,可吹牛的內(nèi)容都是我干的毙芜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼争拐,長吁一口氣:“原來是場噩夢啊……” “哼腋粥!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起架曹,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤隘冲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后绑雄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體展辞,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年万牺,在試婚紗的時候發(fā)現(xiàn)自己被綠了罗珍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡杏愤,死狀恐怖靡砌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情珊楼,我是刑警寧澤通殃,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站厕宗,受9級特大地震影響画舌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜已慢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一曲聂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧佑惠,春花似錦朋腋、人聲如沸齐疙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贞奋。三九已至,卻和暖如春穷绵,著一層夾襖步出監(jiān)牢的瞬間轿塔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工仲墨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留勾缭,地道東北人。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓目养,卻偏偏與公主長得像俩由,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子混稽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評論 2 356

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