Spring?Boot?3.4.3?基于?Spring?WebFlux?實現(xiàn)?SSE?功能(代碼示例)
在現(xiàn)代 Web 應(yīng)用開發(fā)中,實時數(shù)據(jù)推送已成為許多業(yè)務(wù)場景的核心需求,例如實時通知、股票價格更新或在線聊天等。傳統(tǒng)的輪詢方式效率低下,而 SSE(Server-Sent Events,服務(wù)器推送事件)作為 HTML5 提供的一種輕量級技術(shù),能夠通過單向長連接實現(xiàn)服務(wù)器到客戶端的實時數(shù)據(jù)推送。Spring Boot 3.4.3 結(jié)合 Spring WebFlux,為開發(fā)者提供了響應(yīng)式編程能力,使得實現(xiàn) SSE 功能更加簡單高效。本文將詳細(xì)介紹如何在 Spring Boot 3.4.3 中基于 Spring WebFlux 實現(xiàn) SSE 功能,并提供完整的代碼示例,助你在企業(yè)級應(yīng)用中快速落地實時推送需求。
1. SSE 簡介
1.1 什么是 SSE?
SSE(Server-Sent Events)是一種基于 HTTP 協(xié)議的服務(wù)器推送技術(shù),允許服務(wù)器主動向客戶端發(fā)送數(shù)據(jù)??蛻舳送ㄟ^建立長連接接收服務(wù)器推送的事件流,適用于需要實時更新的場景。與 WebSocket 相比,SSE 是單向通信(僅服務(wù)器到客戶端),實現(xiàn)更簡單,且瀏覽器原生支持。
1.2 SSE 的優(yōu)點
- 輕量級:基于 HTTP,無需額外協(xié)議支持。
- 簡單性:實現(xiàn)成本低,適合單向推送場景。
- 自動重連:客戶端斷開后可自動嘗試重連。
- 兼容性:HTML5 標(biāo)準(zhǔn),主流瀏覽器均支持。
1.3 適用場景
- 實時通知(如消息提醒)。
- 數(shù)據(jù)監(jiān)控(如服務(wù)器狀態(tài)更新)。
- 單向事件流(如日志推送)。
2. Spring WebFlux 簡介
Spring WebFlux 是 Spring 5 引入的響應(yīng)式 Web 框架,與傳統(tǒng)的 Spring MVC 不同,它基于 Reactor 項目,支持異步非阻塞的編程模型。Spring Boot 3.4.3 默認(rèn)集成了 Spring WebFlux,使得開發(fā)者可以輕松構(gòu)建高并發(fā)、事件驅(qū)動的應(yīng)用。結(jié)合 SSE,WebFlux 的 Flux
數(shù)據(jù)流非常適合處理實時推送需求。
3. 項目實戰(zhàn)
以下是基于 Spring Boot 3.4.3 和 Spring WebFlux 實現(xiàn) SSE 功能的完整步驟。
3.1 添加 Maven 依賴
在 pom.xml
中添加 Spring WebFlux 的依賴:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.4.3</version> </parent> <artifactId>springboot-sse</artifactId> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> </dependencies> </project>
說明:
spring-boot-starter-webflux
提供了 WebFlux 的核心功能和 Reactor 依賴。- Spring Boot 3.4.3 使用 JDK 17,確保編譯器版本匹配。
3.2 創(chuàng)建 SSE 控制器
創(chuàng)建一個控制器,用于推送事件流:
package cn.joyous.sse.controller; import org.springframework.http.MediaType; import org.springframework.http.codec.ServerSentEvent; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Flux; import java.time.Duration; import java.util.concurrent.atomic.AtomicInteger; /** */ @RestController public class SSEController { // 定義一個計數(shù)器,用于模擬數(shù)據(jù)變化 private final AtomicInteger counter = new AtomicInteger(0); @GetMapping(path = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<ServerSentEvent<Integer>> streamEvents() { return Flux.interval(Duration.ofSeconds(1)) .map(seq -> ServerSentEvent.<Integer>builder() .id(String.valueOf(seq)) .event("message") .data(counter.incrementAndGet()) .build()); } }
代碼說明:
@GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE)
:指定返回 SSE 事件流。Flux.interval(Duration.ofSeconds(1))
:每秒生成一個事件。ServerSentEvent.builder()
:構(gòu)造 SSE 事件,包含id
(事件標(biāo)識)、event
(事件類型)和data
(推送數(shù)據(jù))。
3.3 前端頁面示例
創(chuàng)建一個簡單的 HTML 頁面,用于接收 SSE 數(shù)據(jù):
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>SSE Demo</title> </head> <body> <h1>SSE 數(shù)據(jù)推送</h1> <div id="result"></div> <script> const eventSource = new EventSource("http://localhost:8080/sse"); eventSource.onmessage = function(event) { document.getElementById("result").innerText += "收到數(shù)據(jù): " + event.data + "\n"; }; eventSource.onerror = function() { console.log("SSE 連接失敗"); eventSource.close(); }; </script> </body> </html>
保存為 sse.html
,放置在 src/main/resources/static
目錄下。
3.4 啟動與測試
- 啟動 Spring Boot 應(yīng)用。
- 在瀏覽器中訪問
http://localhost:8080/sse.html
,你將看到頁面每秒更新一次計數(shù)器數(shù)據(jù)。 - 或者直接訪問
http://localhost:8080/sse
,查看原始事件流:
id: 0 event: message data: 1 id: 1 event: message data: 2
4. 進階功能(可選)
自定義事件類型
修改控制器支持多種事件:
@GetMapping(path = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<ServerSentEvent<String>> streamEvents() { return Flux.interval(Duration.ofSeconds(1)) .map(seq -> ServerSentEvent.<String>builder() .id(String.valueOf(seq)) .event(seq % 2 == 0 ? "even" : "odd") .data("Count: " + counter.incrementAndGet()) .build()); }
動態(tài)推送特定用戶
使用 Map 存儲用戶連接:
private final Map<String, Sinks.Many<String>> userSinks = new ConcurrentHashMap<>(); @GetMapping("/sse/{userId}") public Flux<ServerSentEvent<String>> userStream(@PathVariable String userId) { Sinks.Many<String> sink = userSinks.computeIfAbsent(userId, k -> Sinks.many().multicast().onBackpressureBuffer()); return sink.asFlux().map(data -> ServerSentEvent.builder().data(data).build()); }
異常處理
添加錯誤重連邏輯:
return Flux.interval(Duration.ofSeconds(1)) .map(seq -> ServerSentEvent.<Integer>builder().data(counter.incrementAndGet()).build()) .onErrorResume(e -> Flux.just(ServerSentEvent.builder().data("Error: " + e.getMessage()).build()));
5. 總結(jié)
Spring Boot 3.4.3 結(jié)合 Spring WebFlux 實現(xiàn) SSE 功能,為實時數(shù)據(jù)推送提供了優(yōu)雅的解決方案。通過本文的步驟,你可以快速搭建一個基于事件驅(qū)動的后端服務(wù),滿足實時通知或監(jiān)控等需求。相比 WebSocket,SSE 更輕量且易于集成,適合單向推送場景。
到此這篇關(guān)于Spring Boot 3.4.3 基于 Spring WebFlux 實現(xiàn) SSE 功能的文章就介紹到這了,更多相關(guān)Spring Boot Spring WebFlux SSE內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring?main方法中如何調(diào)用Dao層和Service層的方法
這篇文章主要介紹了Spring?main方法中調(diào)用Dao層和Service層的方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12springboot搭建訪客管理系統(tǒng)的實現(xiàn)示例
這篇文章主要介紹了springboot搭建訪客管理系統(tǒng)的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01升級springboot3之自動配置導(dǎo)入失效問題及解決
這篇文章主要介紹了升級springboot3之自動配置導(dǎo)入失效問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07Mybatis自關(guān)聯(lián)查詢一對多查詢的實現(xiàn)示例
這篇文章主要介紹了Mybatis自關(guān)聯(lián)查詢一對多查詢的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02在同一個類中調(diào)用帶有@Transactional注解的方法示例
這篇文章主要為大家介紹了在同一個類中調(diào)用帶有@Transactional注解的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-04-04