SpringBoot+SseEmitter和Vue3+EventSource實現(xiàn)實時數(shù)據(jù)推送
更新時間:2025年03月04日 08:33:29 作者:麥當(dāng)勞不要薯條
本文主要介紹了SpringBoot+SseEmitter和Vue3+EventSource實現(xiàn)實時數(shù)據(jù)推送,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
EventSource 的優(yōu)點
- 簡單易用:EventSource 使用簡單,基于標(biāo)準(zhǔn)的 HTTP 協(xié)議,無需復(fù)雜的握手過程。
- 自動重連:EventSource 具有內(nèi)置的重連機制,確保連接中斷后自動重新連接。
- 輕量級:EventSource 使用長輪詢機制,消耗的資源相對較少,適合低帶寬環(huán)境。
- 跨域支持:EventSource 允許在跨域環(huán)境下進(jìn)行通信,通過適當(dāng)?shù)捻憫?yīng)頭授權(quán)來自不同域的客戶端連接。
1、SpringBoot實現(xiàn)SseEmitter
1.1簡易業(yè)務(wù)層
import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * Author tm * Date 2023/9/25 * Version 1.0 */ @RestController @RequestMapping(path = "/sysTest/see") public class SseControllerTest { private static Map<String, SseEmitter> sseCache = new ConcurrentHashMap<>(); /** * 前端傳遞標(biāo)識,生成唯一的消息通道 */ @GetMapping(path = "subscribe", produces = {MediaType.TEXT_EVENT_STREAM_VALUE}) public SseEmitter push(String id) throws IOException { // 超時時間設(shè)置為3s,用于演示客戶端自動重連 SseEmitter sseEmitter = new SseEmitter(30000L); // 設(shè)置前端的重試時間為1s sseEmitter.send(SseEmitter.event().reconnectTime(1000).data("連接成功")); sseCache.put(id, sseEmitter); System.out.println("add " + id); sseEmitter.onTimeout(() -> { System.out.println(id + "超時"); sseCache.remove(id); }); sseEmitter.onCompletion(() -> System.out.println("完成?。?!")); return sseEmitter; } /** * 根據(jù)標(biāo)識傳遞信息 */ @GetMapping(path = "push") public String push(String id, String content) throws IOException { SseEmitter sseEmitter = sseCache.get(id); if (sseEmitter != null) { sseEmitter.send(SseEmitter.event().name("msg").data("后端發(fā)送消息:" + content)); } return "over"; } /** * 根據(jù)標(biāo)識移除SseEmitter */ @GetMapping(path = "over") public String over(String id) { SseEmitter sseEmitter = sseCache.get(id); if (sseEmitter != null) { sseEmitter.complete(); sseCache.remove(id); } return "over"; } }
2、Vue3對接EventSource
const initEventSource = ()=>{ if (typeof (EventSource) !== 'undefined') { const evtSource = new EventSource('https://xxx.xxx.x.x/sysTest/see/subscribe?id=002', { withCredentials: true }) // 后端接口,要配置允許跨域?qū)傩? // 與事件源的連接剛打開時觸發(fā) evtSource.onopen = function(e){ console.log(e); } // 當(dāng)從事件源接收到數(shù)據(jù)時觸發(fā) evtSource.onmessage = function(e){ console.log(e); } // 與事件源的連接無法打開時觸發(fā) evtSource.onerror = function(e){ console.log(e); evtSource.close(); // 關(guān)閉連接 } // 也可以偵聽命名事件,即自定義的事件 evtSource.addEventListener('msg', function(e) { console.log(e.data) }) } else { console.log('當(dāng)前瀏覽器不支持使用EventSource接收服務(wù)器推送事件!'); } }
3、測試、驗證、使用
使用postMan調(diào)用接口測試
3.1、 postMan調(diào)用后端"push"接口發(fā)送消息
3.2、前端實時接收到數(shù)據(jù)
4、踩坑
4.1、nginx對于EventSource連接要特殊處理
#eventSource location /es/ { proxy_pass http://請求地址/; #必須要設(shè)置當(dāng)前Connection 屬性 proxy_set_header Connection ''; proxy_http_version 1.1; chunked_transfer_encoding off; proxy_buffering off; proxy_cache off; }
4.2、連接通道接口類型一定要設(shè)置MediaType.TEXT_EVENT_STREAM_VALUE
4.3、 跨越問題,項目地址和接口地址需要在同一域名下
4.4 、EventSource監(jiān)聽事件的類型需要與后端發(fā)送的類型一致
到此這篇關(guān)于SpringBoot+SseEmitter和Vue3+EventSource實現(xiàn)實時數(shù)據(jù)推送的文章就介紹到這了,更多相關(guān)SpringBoot 實時數(shù)據(jù)推送內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis-Plus實現(xiàn)公共字段自動賦值的方法
這篇文章主要介紹了Mybatis-Plus實現(xiàn)公共字段自動賦值的方法,涉及到通用字段自動填充的最佳實踐總結(jié),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07詳解利用Spring的AbstractRoutingDataSource解決多數(shù)據(jù)源的問題
本篇文章主要介紹了詳解利用Spring的AbstractRoutingDataSource解決多數(shù)據(jù)源的問題。具有一定的參考價值,有興趣的可以了解一下。2017-03-03Java編程實現(xiàn)提取文章中關(guān)鍵字的方法
這篇文章主要介紹了Java編程實現(xiàn)提取文章中關(guān)鍵字的方法,較為詳細(xì)的分析了Java提取文章關(guān)鍵字的原理與具體實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11