項(xiàng)目需求:數(shù)據(jù)展示實(shí)時(shí)更新
解決方案:在第一時(shí)間想到的是通過前端輪詢的方式請(qǐng)求后端接口,達(dá)到數(shù)據(jù)更新的目的,但是存在以下缺點(diǎn)
數(shù)據(jù)不能做到實(shí)施更新,有一定時(shí)間的延遲
消耗大量的系統(tǒng)資源
優(yōu)化方案:使用EventSource的方式來實(shí)現(xiàn)該需求,能夠解決以上問題
目錄
1. EventSource基本介紹
2. EventSource特性
3. EventSource工作原理
4. EventSource常用方法
5. 實(shí)戰(zhàn)案例:Vue+SpringBoot
1. EventSource基本介紹
EventSource是一種用于實(shí)現(xiàn)服務(wù)器推送事件的Web API,它允許服務(wù)器向客戶端發(fā)送數(shù)據(jù)流,而無需客戶端發(fā)出請(qǐng)求。EventSource架構(gòu)的設(shè)計(jì)思想是建立一種持久連接,通過這個(gè)連接發(fā)送事件流,以實(shí)現(xiàn)通信。
2. EventSource特性
實(shí)時(shí)性。EventSource能夠?qū)崿F(xiàn)實(shí)時(shí)地?cái)?shù)據(jù)傳輸,可以在服務(wù)器端有新事件時(shí)立即向客戶端推送,并自動(dòng)進(jìn)行展示。
低延遲。由于EventSource采用長連接的方式進(jìn)行傳輸,相比于普通的輪詢方式,它能夠更加高效地傳輸數(shù)據(jù)。
易用性。EventSource是一種非常易用的API,只需要在客戶端創(chuàng)建一個(gè)EventSource對(duì)象,指定服務(wù)器端的URL,即可進(jìn)行監(jiān)聽并展示事件。
兼容性。EventSource能夠同時(shí)兼容WebSocket和長輪詢等方式,具備很好的兼容性,可以在各種不同的場(chǎng)景下使用。
3. EventSource工作原理
EventSource的原理基于Http協(xié)議,它允許服務(wù)器與客戶端建立持久的連接,以便服務(wù)器能夠向客戶端推送事件數(shù)據(jù)。以下是EventSource的工作原理客戶端發(fā)起請(qǐng)求:客戶端通過創(chuàng)建一個(gè)EventSource對(duì)象,并向服務(wù)器發(fā)起一個(gè)HTTP GET請(qǐng)求,請(qǐng)求一個(gè)特定的URL。
服務(wù)器響應(yīng):服務(wù)器接收客戶端的請(qǐng)求,并在HTTP頭中添加Content-Type: text/event-stream
,表明將發(fā)送的事件數(shù)據(jù)格式為text/event-stream。
建立持久連接:服務(wù)器與客戶端建立一個(gè)持續(xù)的HTTP連接,并開始向客戶端發(fā)送數(shù)據(jù),直到連接被關(guān)閉。
發(fā)送事件數(shù)據(jù):當(dāng)服務(wù)器有新的事件數(shù)據(jù)要發(fā)送時(shí),它將按照特定格式發(fā)送給客戶端。事件數(shù)據(jù)通常以event:eventName;data:eventData;
的形式發(fā)送,其中event
字段表示事件名,data
字段表示事件數(shù)據(jù)。
客戶端接收數(shù)據(jù):客戶端通過EventSource對(duì)象注冊(cè)事件處理函數(shù),以接收來自服務(wù)器的事件數(shù)據(jù)。當(dāng)接收到事件數(shù)據(jù)時(shí),客戶端會(huì)創(chuàng)建一個(gè)Event對(duì)象,并觸發(fā)相應(yīng)的事件處理函數(shù),傳遞Event對(duì)象作為參數(shù)。Event對(duì)象包含type
(事件類型,通常為"message")、data
(事件數(shù)據(jù))、lastEventId
(上一個(gè)事件的ID)、origin
(事件源的URL)等屬性。
錯(cuò)誤處理和重連:如果連接出現(xiàn)錯(cuò)誤或被關(guān)閉,客戶端將觸發(fā)“error”事件或“close”事件,以便進(jìn)行錯(cuò)誤處理或重新連接。
單向通信:EventSource支持單向通信,即只能從服務(wù)器向客戶端推送數(shù)據(jù),不支持客戶端向服務(wù)器發(fā)送數(shù)據(jù)。這種特性使它適用于需要實(shí)時(shí)更新的應(yīng)用程序場(chǎng)景,如聊天室、股票市場(chǎng)等。
自動(dòng)重連接:EventSource支持自動(dòng)重連接功能,如果連接中斷,它可以嘗試自動(dòng)恢復(fù)連接。
發(fā)送隨機(jī)事件:EventSource允許服務(wù)器發(fā)送沒有明確事件名的隨機(jī)事件,這種情況下,如果沒有指定事件名的匹配事件處理函數(shù),則會(huì)觸發(fā)通用事件處理函數(shù)。
總的來說,EventSource提供了一種簡單的方式來實(shí)現(xiàn)服務(wù)器向客戶端的實(shí)時(shí)數(shù)據(jù)推送,特別適合于不需要雙向通信的場(chǎng)景。
4. EventSource常用方法
1. 創(chuàng)建EventSource對(duì)象,其中url是服務(wù)器端推送數(shù)據(jù)的地址。
var evtSource = new EventSource(url);
2. onopen:連接建立時(shí)觸發(fā)
evtSource.onopen = function () {
console.log("Connection to server opened.");
3. onmessage:接收到服務(wù)器端發(fā)送的數(shù)據(jù)時(shí)觸發(fā)。
evtSource.onmessage = (e) => {
4. onerror:連接出錯(cuò)時(shí)觸發(fā)。
evtSource.onerror = function () {
5. 實(shí)戰(zhàn)案例:Vue+SpringBoot
前端代碼:
methods: {
handleEventSoure() {
const eventSource = new EventSource('/source/test') // 連接地址
eventSource.onopen = () => { // 開始連接
console.log("連接成功")
}
eventSource.onmessage = (event) => { // 接收消息
console.log(event.data)
}
eventSource.onerror = () => { // 連接失敗
console.log("連接失敗")
}
},
},
mounted() {
this.handleEventSoure()
}
后端代碼:
@RestController
@RequestMapping("/source")
public class SysLoginInfoController extends BaseController {
@GetMapping("/test")
public Flux<String> test(HttpServletResponse response, HttpServletRequest req) {
//設(shè)置響應(yīng)的內(nèi)容類型為HTML,字符集為UTF-8。
response.setContentType("text/html;charset=utf-8");
// 設(shè)置響應(yīng)頭,指明這是一個(gè)EventSource響應(yīng)
response.setHeader("Content-Type", "text/event-stream");
//設(shè)置響應(yīng)頭"Cache-Control"為"no-cache",表示不允許緩存此響應(yīng)。
response.setHeader("Cache-Control", "no-cache");
//設(shè)置響應(yīng)頭"Connection"為"keep-alive",表示保持連接。
response.setHeader("Connection", "keep-alive");
//返回的是一個(gè)字符串流 返回?cái)?shù)據(jù):好的 + 當(dāng)前時(shí)間
return Flux.interval(Duration.ofSeconds(1)).map(sequence -> "data: 好的" + new Date() + "");
}
}
效果展示:
至此大功告成。
該文章在 2024/6/15 11:13:24 編輯過