Spring Boot 整合 SSE的高級(jí)實(shí)踐(Server-Sent Events)
1、簡(jiǎn)述
SSE(Server-Sent Events)是一種基于HTTP協(xié)議的單向通信機(jī)制,允許服務(wù)器向?yàn)g覽器持續(xù)發(fā)送實(shí)時(shí)更新。與WebSocket不同,SSE更簡(jiǎn)單,使用HTTP/1.1協(xié)議即可,不需要額外的協(xié)議升級(jí)。
SSE的特點(diǎn):
- 單向通信:服務(wù)器推送數(shù)據(jù)給客戶端,客戶端無法向服務(wù)器發(fā)送消息。
- 簡(jiǎn)單易用:基于HTTP協(xié)議,無需復(fù)雜的配置。
- 瀏覽器支持:現(xiàn)代瀏覽器大多內(nèi)置支持(如Chrome、Edge、Firefox等)。
2、Spring Boot 中的SSE實(shí)現(xiàn)
2.1 添加依賴
SSE無需額外的依賴,Spring Boot自帶對(duì)SSE的支持。創(chuàng)建一個(gè)Spring Boot項(xiàng)目即可。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2.2 實(shí)現(xiàn)后端接口
使用MediaType.TEXT_EVENT_STREAM_VALUE
作為返回類型即可開啟SSE。以下代碼是一個(gè)簡(jiǎn)單的實(shí)現(xiàn)。
package com.example.sse.controller; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.time.LocalTime; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; @RestController public class SseController { @GetMapping(value = "/sse/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Stream<String> stream() { // 模擬數(shù)據(jù)流 return Stream.generate(() -> "當(dāng)前時(shí)間:" + LocalTime.now()) .limit(10); // 限制10條消息 } }
2.3 配置超時(shí)時(shí)間(可選)
默認(rèn)情況下,Spring Boot的響應(yīng)會(huì)超時(shí)。可以在application.properties
中調(diào)整超時(shí)時(shí)間:
server.servlet.session.timeout=30s spring.mvc.async.request-timeout=30000
2.4 前端實(shí)現(xiàn)
SSE在前端通過EventSource
對(duì)象實(shí)現(xiàn)。以下是一個(gè)簡(jiǎn)單的前端示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>SSE Example</title> </head> <body> <h1>實(shí)時(shí)消息</h1> <div id="messages"></div> <script> const eventSource = new EventSource('/sse/stream'); eventSource.onmessage = function(event) { const messagesDiv = document.getElementById('messages'); const newMessage = document.createElement('p'); newMessage.textContent = event.data; messagesDiv.appendChild(newMessage); }; eventSource.onerror = function() { console.error('SSE連接出錯(cuò),正在嘗試重連...'); eventSource.close(); }; </script> </body> </html>
3、高級(jí)實(shí)踐
使用Spring Scheduler推送數(shù)據(jù),在實(shí)際場(chǎng)景中,可能需要定時(shí)向客戶端推送數(shù)據(jù)。例如,監(jiān)控系統(tǒng)定時(shí)更新。
package com.example.sse.service; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import java.io.IOException; import java.util.concurrent.CopyOnWriteArrayList; @Service public class SsePushService { private final CopyOnWriteArrayList<SseEmitter> emitters = new CopyOnWriteArrayList<>(); public SseEmitter subscribe() { SseEmitter emitter = new SseEmitter(30_000L); emitters.add(emitter); emitter.onCompletion(() -> emitters.remove(emitter)); emitter.onTimeout(() -> emitters.remove(emitter)); return emitter; } public void pushMessage(String message) { for (SseEmitter emitter : emitters) { try { emitter.send(message, MediaType.TEXT_PLAIN); } catch (IOException e) { emitters.remove(emitter); } } } }
創(chuàng)建一個(gè)控制器訂閱和推送消息:
package com.example.sse.controller; import com.example.sse.service.SsePushService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class SsePushController { private final SsePushService ssePushService; public SsePushController(SsePushService ssePushService) { this.ssePushService = ssePushService; } @GetMapping("/sse/subscribe") public SseEmitter subscribe() { return ssePushService.subscribe(); } @GetMapping("/sse/push") public void pushMessage() { ssePushService.pushMessage("當(dāng)前時(shí)間:" + System.currentTimeMillis()); } }
注意事項(xiàng):
- 瀏覽器兼容性:SSE不支持IE,但現(xiàn)代瀏覽器支持良好。
- 連接斷開處理:可通過
EventSource
的onerror
事件重新連接。 - 性能問題:對(duì)大量訂閱者時(shí),需考慮使用分布式消息隊(duì)列優(yōu)化(如Kafka)。
- 超時(shí)時(shí)間:默認(rèn)30秒超時(shí),需要根據(jù)實(shí)際需求調(diào)整。
4、適用場(chǎng)景
- 實(shí)時(shí)通知:如監(jiān)控系統(tǒng)的告警推送。
- 實(shí)時(shí)更新:如股票行情、體育比分。
- 消息流:如系統(tǒng)日志、任務(wù)進(jìn)度。
到此這篇關(guān)于Spring Boot 整合 SSE(Server-Sent Events)的文章就介紹到這了,更多相關(guān)Spring Boot 整合 SSE內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java工程使用ffmpeg進(jìn)行音視頻格式轉(zhuǎn)換的實(shí)現(xiàn)
FFmpeg是一套可以用來記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開源計(jì)算機(jī)程序,本文主要介紹了Java工程使用ffmpeg進(jìn)行音視頻格式轉(zhuǎn)換的實(shí)現(xiàn)2024-02-02mybatis如何對(duì)大量數(shù)據(jù)的游標(biāo)查詢
這篇文章主要介紹了mybatis如何對(duì)大量數(shù)據(jù)的游標(biāo)查詢問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01Java使用poi-tl1.9.1生成Word文檔的技巧分享
本文將簡(jiǎn)單介紹poi-tl的相關(guān)知識(shí),通過一個(gè)實(shí)際的案例實(shí)踐,充分介紹如何利用poi-tl進(jìn)行目標(biāo)文檔的生成,同時(shí)分享幾個(gè)不同的office版本如何進(jìn)行圖表生成的解決方案,需要的朋友可以參考下2023-09-09SpringBoot集成antlr實(shí)現(xiàn)詞法和語法分析
Antlr4 是一款強(qiáng)大的語法生成器工具,可用于讀取、處理、執(zhí)行和翻譯結(jié)構(gòu)化的文本或二進(jìn)制文件,基本上是當(dāng)前 Java 語言中使用最為廣泛的語法生成器工具,本文給大家介紹了SpringBoot集成antlr實(shí)現(xiàn)詞法和語法分析,需要的朋友可以參考下2024-06-06Java輕松實(shí)現(xiàn)批量插入或刪除Excel行列操作
在職場(chǎng)生活中,對(duì)Excel工作表的行和列進(jìn)行操作是非常普遍的需求,下面小編就來和大家介紹一下如何在Java中完成批量插入、刪除行和列的操作吧2023-10-10解決spring?data?jpa?saveAll()?保存過慢問題
這篇文章主要介紹了解決spring?data?jpa?saveAll()保存過慢問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11