實(shí)時(shí)數(shù)據(jù)推送并非只有WebSocket一種選擇,還有SSE、長(zhǎng)輪詢等
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
環(huán)境:SpringBoot2.7.16 概述在Web應(yīng)用中,有幾種實(shí)時(shí)數(shù)據(jù)推送的選擇方案,包括SSE(Server-Sent Events)、WebSocket、長(zhǎng)輪詢等。 SSE是一種基于HTTP協(xié)議的服務(wù)器向客戶端推送數(shù)據(jù)的技術(shù)。它的優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單、輕量級(jí),對(duì)現(xiàn)有服務(wù)器軟件兼容性好。但是,由于SSE是單向通信模型,只能由服務(wù)器向客戶端推送數(shù)據(jù),對(duì)于需要客戶端向服務(wù)器發(fā)送數(shù)據(jù)的場(chǎng)景,SSE就無(wú)法滿足需求。 WebSocket是一種雙向通信模型,允許客戶端和服務(wù)器之間互相發(fā)送消息。它的優(yōu)點(diǎn)是實(shí)時(shí)性強(qiáng)、延遲低,但是需要服務(wù)器端支持對(duì)應(yīng)的協(xié)議棧,實(shí)現(xiàn)起來(lái)相對(duì)復(fù)雜一些。 長(zhǎng)輪詢是對(duì)短輪詢的一種改進(jìn)版本,通過(guò)在盡可能減少對(duì)服務(wù)器資源浪費(fèi)的同時(shí),保證消息的相對(duì)實(shí)時(shí)性。長(zhǎng)輪詢?cè)诳蛻舳税l(fā)起請(qǐng)求時(shí),服務(wù)器會(huì)保持連接打開,等待一定時(shí)間后再返回響應(yīng)。這樣可以減少客戶端頻繁的請(qǐng)求,節(jié)省帶寬和服務(wù)器資源。但是,如果服務(wù)器沒(méi)有新的消息產(chǎn)生,客戶端會(huì)一直等待響應(yīng),實(shí)時(shí)性就會(huì)受到一定影響。 根據(jù)實(shí)際應(yīng)用場(chǎng)景和需求,可以選擇適合的實(shí)時(shí)數(shù)據(jù)推送方案。如果只需要服務(wù)器向客戶端推送數(shù)據(jù),且對(duì)實(shí)時(shí)性要求不是特別高,可以選擇SSE。如果需要客戶端向服務(wù)器發(fā)送數(shù)據(jù),或者對(duì)實(shí)時(shí)性要求較高,可以選擇WebSocket或長(zhǎng)輪詢。當(dāng)然,也可以根據(jù)實(shí)際情況將這幾種方案結(jié)合起來(lái)使用,以滿足不同的需求。 SSE與WebSocket對(duì)比SSE(Server-Sent Events)和WebSocket都是用于實(shí)現(xiàn)實(shí)時(shí)通信的技術(shù),存在關(guān)鍵差異。 通信模型:SSE是單向通信模型,只能由服務(wù)器向客戶端推送數(shù)據(jù)。而WebSocket是雙向通信模型,客戶端和服務(wù)器可以互相發(fā)送消息。 連接性:SSE使用長(zhǎng)輪詢或HTTP流技術(shù),需要頻繁地發(fā)起HTTP請(qǐng)求來(lái)獲取數(shù)據(jù)。而 WebSocket只需在握手階段建立一次連接,然后保持連接打開,減少了頻繁建立連接的開銷。 實(shí)時(shí)性:WebSocket提供了更低的延遲和更高的實(shí)時(shí)性,因?yàn)樗С蛛p向通信,可以立即將數(shù)據(jù)推送給客戶端。SSE雖然也可以實(shí)現(xiàn)實(shí)時(shí)性,但由于其單向通信模型,需要服務(wù)器定期發(fā)送數(shù)據(jù)。 協(xié)議特性:SSE是部署在HTTP協(xié)議之上的,現(xiàn)有的服務(wù)器軟件都支持。而WebSocket是一個(gè)新的協(xié)議,需要服務(wù)器端支持對(duì)應(yīng)的協(xié)議棧。 復(fù)雜性:SSE相對(duì)WebSocket來(lái)說(shuō)更輕量級(jí),實(shí)現(xiàn)更簡(jiǎn)單。WebSocket協(xié)議較復(fù)雜,實(shí)現(xiàn)相對(duì)困難一些。 總體來(lái)說(shuō),SSE和WebSocket都有各自的優(yōu)點(diǎn)和適用場(chǎng)景。SSE輕量級(jí)且對(duì)現(xiàn)有服務(wù)器軟件兼容性好,而WebSocket則提供了更強(qiáng)的雙向通信能力和更高的實(shí)時(shí)性。 SSE簡(jiǎn)介SSE(Server-Sent Events)是一種用于實(shí)現(xiàn)服務(wù)器向客戶端實(shí)時(shí)推送數(shù)據(jù)的Web技術(shù)。與傳統(tǒng)的輪詢和長(zhǎng)輪詢相比,SSE提供了更高效和實(shí)時(shí)的數(shù)據(jù)推送機(jī)制。 SSE基于HTTP協(xié)議,允許服務(wù)器將數(shù)據(jù)以事件流(Event Stream)的形式發(fā)送給客戶端。客戶端通過(guò)建立持久的HTTP連接,并監(jiān)聽(tīng)事件流,可以實(shí)時(shí)接收服務(wù)器推送的數(shù)據(jù)。 SSE的主要特點(diǎn)包括: 簡(jiǎn)單易用:SSE使用基于文本的數(shù)據(jù)格式,如純文本、JSON等,使得數(shù)據(jù)的發(fā)送和解析都相對(duì)簡(jiǎn)單。 單向通信:SSE支持服務(wù)器向客戶端的單向通信,服務(wù)器可以主動(dòng)推送數(shù)據(jù)給客戶端。 實(shí)時(shí)性:SSE建立長(zhǎng)時(shí)間的連接,使得服務(wù)器可以實(shí)時(shí)地將數(shù)據(jù)推送給客戶端,而無(wú)需客戶端頻繁地發(fā)起請(qǐng)求。 服務(wù)端開發(fā)依賴管理 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> 配置文件 spring: mvc: static-path-pattern: /** web: resources: #靜態(tài)文件目錄index.html static-locations: classpath:/templates/ 接口開發(fā)
前端開發(fā)前端比較簡(jiǎn)單就是一個(gè)index.html頁(yè)面 <html> <head> <title>SSE</title> </head> <body> <button type="button" onclick="closeSse()">Close</button> <hr style="margin: 2px; padding: 0px 0px;"/> <ul id="list"></ul> </body> <script> const evtSource = new EventSource(`/sse/events/${Date.now()}`) ; evtSource.onmessage = (event) => { const newElement = document.createElement("li") ; const eventList = document.getElementById("list") ; newElement.innerHTML = "接收到消息: " + event.data ; eventList.appendChild(newElement) ; }; evtSource.onopen = (event) => { console.log('建立連接...') }; evtSource.onerror = (event) => { console.error("發(fā)生錯(cuò)誤:", event) ; }; function closeSse() { evtSource.close() ; } </script> </html> 以上就是前后端的開發(fā),代碼非常的簡(jiǎn)單;也就簡(jiǎn)單的實(shí)現(xiàn)了由服務(wù)端實(shí)時(shí)數(shù)據(jù)推送。
測(cè)試調(diào)用消息發(fā)送接口 自定義事件類型修改消息發(fā)送接口 @GetMapping("/sender/{id}") public String sender(@PathVariable("id") String id) throws Exception { SseEmitter emitter = this.sse.get(id) ; if (emitter != null) { SseEventBuilder builder = SseEmitter.event() ; // 指定事件類型 builder.name("chat") ; String msg = "隨機(jī)消息 - " + new Random().nextInt(10000000); builder.data(msg) ; try { emitter.send(builder) ; } catch (Exception e) { e.printStackTrace(); } } return "success" ; } 前端監(jiān)聽(tīng)具體事件類型消息
注意:默認(rèn)是“message”事件,因?yàn)樗梢圆东@沒(méi)有 event 字段的事件, * 以及具有特定類型 `event:message` 的事件。* 它不會(huì)觸發(fā)任何其他類型的事件。 完畢!!! 該文章在 2023/10/7 10:58:31 編輯過(guò) |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |