1、前言
目前JS實(shí)時(shí)通信方式主要由:websocket、socket.io、eventSource(SSE)這三種方式。有人就也許好奇有了websocket這種實(shí)時(shí)通信方式,為啥還需要eventSource呢?這是因?yàn)椴煌蛻?hù)端場(chǎng)景,有著各自的優(yōu)勢(shì)。
eventSource是單向通信,而websocket是雙向通信。在新聞推送、股票行情這種只需要服務(wù)器發(fā)送消息給客戶(hù)端場(chǎng)景,使用SSE更加合適,另外SSE是使用HTTP傳輸?shù)摹6鴚ebsocket要求全雙工連接和一個(gè)新的websocket服務(wù)器去處理,
因?yàn)楦饔兴L(zhǎng),我們只需要根據(jù)實(shí)際應(yīng)用場(chǎng)景,去選擇最優(yōu)的應(yīng)用方案。
2、介紹
EventSource 對(duì)象接口用于接收服務(wù)器發(fā)送的事件。它通過(guò) HTTP 連接到服務(wù)器,已 text/event-stream
格式接收事件,不關(guān)閉連接。
EventSource 對(duì)象主要用于 Server-Sent Events(簡(jiǎn)稱(chēng) SSE)的技術(shù)。這是一種能讓瀏覽器通過(guò) HTTP 連接自動(dòng)收到服務(wù)器端更新的技術(shù)。
這個(gè)技術(shù)的作用是可以完成從服務(wù)器端到客戶(hù)端(瀏覽器)單向的消息傳遞。因此我們可以用這個(gè)來(lái)做推送。
相關(guān)文檔:https://developer.mozilla.org/zh-CN/docs/Web/API/EventSource
2.1瀏覽器兼容性
2.2構(gòu)造函數(shù)
const eventSource = new EventSource()
2.3屬性
說(shuō)明 | 屬性 |
---|
onerror | 當(dāng)發(fā)生錯(cuò)誤時(shí)被調(diào)用,并且在此對(duì)象上派發(fā) error 事件 |
onmessage | 服務(wù)器端發(fā)送給客戶(hù)端一條消息時(shí)觸發(fā) |
onopen | SSE 連接剛打開(kāi)時(shí)觸發(fā) |
readyState | 表示連接狀態(tài)(CONNECTING 、OPEN 和 CLOSED ) |
url | 代表源頭的 URL |
2.4方法
方法 | 說(shuō)明 |
---|
close | 關(guān)閉連接 |
2.5通信過(guò)程
在瀏覽器通信截圖:
2.6服務(wù)端
服務(wù)端返回響應(yīng)頭必須包含以下header:
Content-Type: text/event-steam
Cache-Control: no-cache
Connection: keep-alive
服務(wù)器返回的數(shù)據(jù)格式為文本型,由若干個(gè)message組成,每個(gè)message用\n\n分割
每個(gè)message內(nèi)容是[key]:value
key有四種情況:id、event(type)、data、tetry
id 為每個(gè)返回?cái)?shù)據(jù)的唯一標(biāo)識(shí),瀏覽器用lastEventId讀取id,一旦連接斷開(kāi),瀏覽器會(huì)從新發(fā)送http請(qǐng)求,帶有特殊請(qǐng)求頭Last-Event-Id,代表斷開(kāi)時(shí)的id,用于建立重新連接,屬于一種重連的同步機(jī)制.
data 數(shù)據(jù)內(nèi)容一般放于data字段。
event(type):消息類(lèi)型,一般默認(rèn)為message,服務(wù)端可以自定義,前端用addEventListener()監(jiān)聽(tīng)。
retry:代表服務(wù)器重新發(fā)送請(qǐng)求的間隔時(shí)間。
3、實(shí)例運(yùn)用
3.1原生EventSource
/*
* new EventSource(url, configuration)
* url:請(qǐng)求地址路徑
* configuration 可選項(xiàng):withCredentials,默認(rèn)為false,指是否CORS設(shè)置
*
*/
const eventSource = new EventSource('/api/stream');
// 正常的EventSource,我們只關(guān)心以下三個(gè)事件
/*
* open:訂閱成功(和后端連接成功)
*/
eventSource.addEventListener("open", function(e) {
console.log('open successfully')
})
/*
* message:后端返回信息,格式可以和后端協(xié)商
*/
eventSource.addEventListener("message", function(e) {
console.log(e.data)
})
/*
* error:錯(cuò)誤(可能是斷開(kāi),可能是后端返回的信息)
*/
eventSource.addEventListener("error", function(err) {
console.log(err)
// 類(lèi)似的返回信息驗(yàn)證,這里是實(shí)例
err && err.status === 401 && console.log('not authorized')
})
// 需要關(guān)閉了
eventSource.close()
注意:因?yàn)樵鶨ventSource無(wú)法進(jìn)行自定義配置,例如header、method等,因此我們需要引用其他的封裝庫(kù)
3.2fetch-event-source
使用post的方式請(qǐng)求eventSource
安裝依賴(lài):npm install --save @rangermauve/fetch-event-source
import { fetchEventSource } from '@microsoft/fetch-event-source'
fetchEventSource('/api/stream', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(dataJson),
onopen() {},
onmessage(event) {
const jsonData = JSON.parse(event.data)
let respondTexts = jsonData.delta
let finishStatus = jsonData.finished
},
onerror() {},
onclose() {}
})
該文章在 2024/6/15 11:03:32 編輯過(guò)