SpringBoot整合SSE接口實(shí)現(xiàn)實(shí)時(shí)數(shù)據(jù)推送
一、什么是SSE
SSE(Server-Sent Events) 是一種基于HTTP的服務(wù)器向客戶(hù)端單向?qū)崟r(shí)推送數(shù)據(jù)的技術(shù)。與WebSocket不同,SSE天然支持?jǐn)嗑€重連,且協(xié)議簡(jiǎn)單,適用于股票行情、實(shí)時(shí)日志、消息通知等場(chǎng)景。
二、項(xiàng)目環(huán)境準(zhǔn)備
1. 基礎(chǔ)依賴(lài)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 若使用WebFlux方式 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>
三、兩種實(shí)現(xiàn)方式對(duì)比
特性 | 傳統(tǒng)Servlet方式 | WebFlux響應(yīng)式方式 |
---|---|---|
線程模型 | 阻塞IO(線程池) | 非阻塞IO(事件循環(huán)) |
資源消耗 | 較高 | 較低 |
代碼復(fù)雜度 | 需手動(dòng)管理線程 | 聲明式編程 |
適用場(chǎng)景 | 簡(jiǎn)單低頻場(chǎng)景 | 高并發(fā)實(shí)時(shí)場(chǎng)景 |
四、傳統(tǒng)Servlet實(shí)現(xiàn)(基于SseEmitter)
1. 控制器實(shí)現(xiàn)
@RestController public class SseController { @GetMapping("/sse") public SseEmitter handleSse() { SseEmitter emitter = new SseEmitter(); ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); Runnable task = () -> { try { String data = "Time: " + LocalDateTime.now(); emitter.send( SseEmitter.event() .data(data) .id(String.valueOf(System.currentTimeMillis())) ); } catch (IOException e) { emitter.completeWithError(e); executor.shutdown(); } }; // 定時(shí)發(fā)送(立即執(zhí)行,每秒一次) executor.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS); // 客戶(hù)端斷開(kāi)處理 emitter.onCompletion(executor::shutdown); emitter.onTimeout(executor::shutdown); return emitter; } }
2. 關(guān)鍵點(diǎn)解析
SseEmitter:核心類(lèi),保持長(zhǎng)連接
ScheduledExecutorService:定時(shí)任務(wù)線程池
事件結(jié)構(gòu):支持設(shè)置id/event/data等字段
資源釋放:通過(guò)onCompletion/onTimeout確保線程池關(guān)閉
五、響應(yīng)式實(shí)現(xiàn)(基于WebFlux)
1. 控制器實(shí)現(xiàn)
@RestController public class SseWebFluxController { @GetMapping(value = "/sse-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<ServerSentEvent<String>> streamEvents() { return Flux.interval(Duration.ofSeconds(1)) .map(sequence -> ServerSentEvent.<String>builder() .id(String.valueOf(sequence)) .event("time-update") .data("SSE from WebFlux - " + LocalDateTime.now()) .build()); } }
2. 核心優(yōu)勢(shì)
非阻塞IO:基于Reactor庫(kù)實(shí)現(xiàn)響應(yīng)式流
自動(dòng)背壓:處理客戶(hù)端消費(fèi)速度差異
簡(jiǎn)潔API:使用Flux流式編程
六、接口測(cè)試方法
1. 使用curl測(cè)試
curl http://localhost:8080/sse
curl http://localhost:8080/sse-stream
2. 前端示例
const eventSource = new EventSource('/sse'); eventSource.onmessage = (e) => { console.log('Received:', e.data); }; eventSource.addEventListener('time-update', (e) => { console.log('Custom event:', e.data); });
七、生產(chǎn)環(huán)境注意事項(xiàng)
連接管理:設(shè)置合理的超時(shí)時(shí)間(默認(rèn)30秒)
錯(cuò)誤處理:添加onError回調(diào)記錄異常
跨域配置:需要配置CORS
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/sse*") .allowedOrigins("*"); } }
性能監(jiān)控:跟蹤活躍連接數(shù)
八、擴(kuò)展應(yīng)用場(chǎng)景
實(shí)時(shí)股票報(bào)價(jià)推送
系統(tǒng)運(yùn)行狀態(tài)監(jiān)控
聊天應(yīng)用消息通知
長(zhǎng)耗時(shí)任務(wù)進(jìn)度更新
九、總結(jié)
兩種實(shí)現(xiàn)方式各有優(yōu)勢(shì):
- 傳統(tǒng)Servlet方式 適合簡(jiǎn)單場(chǎng)景,快速實(shí)現(xiàn)
- WebFlux方式 更適合高并發(fā)、低延遲需求
建議根據(jù)實(shí)際場(chǎng)景選擇,對(duì)于新項(xiàng)目推薦使用WebFlux實(shí)現(xiàn),能更好地利用系統(tǒng)資源。希望本文能幫助您快速上手SpringBoot中的SSE開(kāi)發(fā)!
到此這篇關(guān)于SpringBoot整合SSE接口實(shí)現(xiàn)實(shí)時(shí)數(shù)據(jù)推送的文章就介紹到這了,更多相關(guān)SpringBoot SSE實(shí)時(shí)數(shù)據(jù)推送內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java判斷用戶(hù)輸入的是否至少含有N位小數(shù)的實(shí)例
下面小編就為大家分享一篇java判斷用戶(hù)輸入的是否至少含有N位小數(shù)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12通過(guò)Java實(shí)現(xiàn)RSA加密與驗(yàn)證的方法詳解
RSA是一種非對(duì)稱(chēng)加密算法,是目前廣泛應(yīng)用于加密和數(shù)字簽名領(lǐng)域的一種加密算法,本文主要講述如何通過(guò)Java實(shí)現(xiàn)RSA加密與驗(yàn)證,應(yīng)用場(chǎng)景為與其他平臺(tái)對(duì)接接口時(shí),通過(guò)RSA加密和解密驗(yàn)證請(qǐng)求的有效性,在對(duì)接時(shí)雙方互換公鑰,需要的朋友可以參考下2023-12-12IDEA 如何控制編輯左側(cè)的功能圖標(biāo)ICON(操作步驟)
很多朋友被idea左側(cè)的圖標(biāo)不見(jiàn)了這一問(wèn)題搞的焦頭爛額,不知道該怎么操作,今天小編就交大家如何控制編輯左側(cè)的功能圖標(biāo) ICON,文字內(nèi)容不多,主要通過(guò)兩張截圖給大家說(shuō)明,感興趣的朋友一起看看吧2021-05-05Mybatis 動(dòng)態(tài)sql的編寫(xiě)與開(kāi)啟二級(jí)緩存
二級(jí)緩存是Mapper級(jí)別的緩存,多個(gè)SqlSession去操作同一個(gè)Mapper中的SQL語(yǔ)句,則這些SqlSession可以共享二級(jí)緩存,即二級(jí)緩存是跨SqlSession的,這篇文章主要介紹了Mybatis 動(dòng)態(tài)sql的編寫(xiě)|開(kāi)啟二級(jí)緩存,需要的朋友可以參考下2023-02-02SpringBoot項(xiàng)目使用?axis?調(diào)用webservice接口的實(shí)踐記錄
這篇文章主要介紹了SpringBoot項(xiàng)目使用?axis?調(diào)用webservice接口,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06