亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring之SseEmitter實現(xiàn)讓你的進度條實時更新

 更新時間:2025年02月28日 11:13:12   作者:drebander  
Spring SseEmitter是一種實現(xiàn)服務器端推送事件(SSE)的機制,支持單向通信,適用于實時數(shù)據(jù)傳輸需求,通過代碼示例和應用場景分析,展示了如何在服務端和客戶端使用SseEmitter進行實時數(shù)據(jù)推送

在現(xiàn)代 Web 應用中,實時數(shù)據(jù)傳輸已經(jīng)成為一個不可忽視的需求,尤其是在聊天系統(tǒng)、實時數(shù)據(jù)展示、進度推送等場景中。

Spring 提供了 SseEmitter 來支持服務器端推送事件(Server-Sent Events, SSE),它通過 HTTP 協(xié)議允許服務器主動向客戶端推送數(shù)據(jù)。與 WebSocket 不同,SSE 是單向通信,但它也提供了一種輕量、高效的實時數(shù)據(jù)流解決方案。

本文將從原理、實際應用、客戶端和服務端代碼示例、擴展應用場景等方面詳細介紹 Spring SseEmitter。

1. 原理解析

1.1 Server-Sent Events (SSE)

SSE 是一種基于 HTTP 協(xié)議的單向數(shù)據(jù)流技術,允許服務器通過持久化的 HTTP 連接將事件推送到客戶端。其與 WebSocket 的主要區(qū)別是,SSE 是單向通信(從服務器到客戶端),而 WebSocket 是全雙工通信(服務器和客戶端都可以發(fā)送數(shù)據(jù))。

在 SSE 中,客戶端通過 EventSource 對象與服務器建立連接,服務器將數(shù)據(jù)以流的方式推送到客戶端。SSE 使用標準的 HTTP 協(xié)議,并且是基于文本的流,數(shù)據(jù)通常以 text/event-stream 類型的格式傳輸。

1.2 SseEmitter

SseEmitter 是 Spring 提供的一個類,用于實現(xiàn) SSE 功能。它支持向客戶端推送數(shù)據(jù),并且能夠處理長連接。SseEmitter 的主要功能包括:

  • 異步發(fā)送數(shù)據(jù):SSE 是長連接,SseEmitter 可以在服務器端異步發(fā)送數(shù)據(jù)。
  • 支持超時管理:SseEmitter 可以設置超時,若客戶端在指定時間內(nèi)沒有響應,連接會自動關閉。
  • 異常處理:如果發(fā)生錯誤,可以通過 SseEmitter 完成錯誤通知和連接關閉。

2. 服務端代碼實現(xiàn)

2.1 創(chuàng)建 SSE 連接

使用 Spring 的 SseEmitter 來向客戶端推送實時事件非常簡單。

我們通過 @GetMapping 注解來映射一個請求路徑,返回一個 SseEmitter 實例。

@RestController
public class SseController {

    @GetMapping(value = "/sync/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter syncStream() {
        SseEmitter emitter = new SseEmitter();

        // 模擬異步任務,發(fā)送實時數(shù)據(jù)
        new Thread(() -> {
            try {
                for (int i = 0; i <= 100; i++) {
                    emitter.send("data: " + i + "% complete\n\n");
                    Thread.sleep(1000);  // 模擬任務處理
                }
                emitter.complete();  // 任務完成,結束 SSE 流
            } catch (Exception e) {
                emitter.completeWithError(e);  // 出現(xiàn)異常時結束流
            }
        }).start();

        return emitter;
    }
}

在上面的代碼中,syncStream 方法創(chuàng)建了一個 SseEmitter 實例,并使用一個線程模擬了一個處理任務的過程。

每秒鐘將當前進度推送給客戶端,直到進度達到 100%。當任務完成時,通過 emitter.complete() 關閉連接。

  • SseEmitter.send(data): 用于向客戶端推送數(shù)據(jù)。
  • SseEmitter.complete(): 用于標記推送完成,關閉連接。
  • SseEmitter.completeWithError(exception): 如果發(fā)生異常,可以通過此方法結束連接并發(fā)送錯誤信息。

2.2 超時設置

SSE 連接可能會因為網(wǎng)絡問題或其他原因被中斷,Spring 提供了超時設置,確保連接不被無限期阻塞。

@GetMapping(value = "/sync/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter syncStream() {
    SseEmitter emitter = new SseEmitter(30000L);  // 設置超時時間為30秒
    // 發(fā)送數(shù)據(jù)的代碼同上...
    return emitter;
}

3. 客戶端代碼實現(xiàn)

在客戶端,我們可以使用原生的 JavaScript EventSource 對象來接收 SSE 流數(shù)據(jù)。EventSource 會自動管理連接,包括重試和重新連接等操作。

let eventSource = new EventSource("/sync/stream");

eventSource.onmessage = function(event) {
    console.log("Received message: ", event.data);
};

eventSource.onerror = function(error) {
    console.error("EventSource failed: ", error);
};
  • new EventSource("/sync/stream"): 創(chuàng)建一個連接到指定 URL 的 EventSource 實例。
  • onmessage: 每當服務器發(fā)送一個事件時,會觸發(fā)該事件。
  • onerror: 當發(fā)生錯誤時,會觸發(fā)該事件。

4. 擴展應用場景

4.1 實時任務進度推送

可以利用 SseEmitter 來推送后臺任務的實時進度。

例如,在執(zhí)行一個需要時間的任務時,可以定期向客戶端推送進度更新。

@GetMapping("/task/progress")
public SseEmitter streamTaskProgress() {
    SseEmitter emitter = new SseEmitter();
    new Thread(() -> {
        try {
            for (int i = 0; i <= 100; i++) {
                emitter.send("data: " + i + "% complete\n\n");
                Thread.sleep(1000);  // 模擬任務處理
            }
            emitter.complete();  // 任務完成,結束 SSE 流
        } catch (Exception e) {
            emitter.completeWithError(e);  // 出現(xiàn)異常時結束流
        }
    }).start();
    return emitter;
}

4.2 實時聊天系統(tǒng)

在實時聊天應用中,可以使用 SSE 向所有連接的客戶端推送消息。

@GetMapping("/chat/{roomId}")
public SseEmitter streamChatMessages(@PathVariable String roomId) {
    SseEmitter emitter = new SseEmitter();
    chatService.addListener(roomId, message -> {
        try {
            emitter.send("data: " + message + "\n\n");
        } catch (IOException e) {
            emitter.completeWithError(e);
        }
    });
    return emitter;
}

在這個例子中,

chatService.addListener(roomId, message -> {...}) 

是監(jiān)聽指定聊天室消息的邏輯,所有聊天信息都會通過 SseEmitter.send() 推送到客戶端。

4.3 動態(tài)數(shù)據(jù)顯示

SSE 適用于動態(tài)顯示數(shù)據(jù)更新的場景,比如股票價格、天氣預報等實時數(shù)據(jù)。

@GetMapping("/live-stock/{symbol}")
public SseEmitter streamStockPrice(@PathVariable String symbol) {
    SseEmitter emitter = new SseEmitter();
    stockService.addPriceListener(symbol, price -> {
        try {
            emitter.send("data: " + price + "\n\n");
        } catch (IOException e) {
            emitter.completeWithError(e);
        }
    });
    return emitter;
}

在這個例子中,

stockService.addPriceListener(symbol, price -> {...})

監(jiān)聽股票的實時價格變化,并通過 SseEmitter.send() 將最新價格推送到客戶端。

5. 總結

Spring 的 SseEmitter 提供了一種簡潔且高效的方式來實現(xiàn)服務器向客戶端推送實時事件。通過 SSE,我們可以輕松地在后臺執(zhí)行長時間任務,并將實時數(shù)據(jù)推送給前端應用。

SSE 適用于許多場景,如任務進度推送、實時消息通知、動態(tài)數(shù)據(jù)展示等。相較于 WebSocket,SSE 實現(xiàn)簡單,且不需要額外的協(xié)議支持,適合輕量級的實時應用。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • SpringBoot QQ郵箱發(fā)送郵件實例代碼

    SpringBoot QQ郵箱發(fā)送郵件實例代碼

    大家好,本篇文章主要講的是SpringBoot QQ郵箱發(fā)送郵件實例代碼,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Java 數(shù)據(jù)結構與算法系列精講之排序算法

    Java 數(shù)據(jù)結構與算法系列精講之排序算法

    排序算法是《數(shù)據(jù)結構與算法》中最基本的算法之一。排序算法可以分為內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存
    2022-02-02
  • 養(yǎng)成良好java代碼編碼規(guī)范

    養(yǎng)成良好java代碼編碼規(guī)范

    這篇文章主要介紹了如何養(yǎng)成良好java代碼編碼規(guī)范,規(guī)范需要平時編碼過程中注意,是一個慢慢養(yǎng)成的好習慣,下面小編就帶大家來一起詳細了解一下吧
    2019-06-06
  • 解決idea每次新建項目都需要重新指定maven目錄

    解決idea每次新建項目都需要重新指定maven目錄

    這篇文章主要介紹了解決idea每次新建項目都需要配置maven,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • SpringBoot如何實現(xiàn)一個實時更新的進度條的示例代碼

    SpringBoot如何實現(xiàn)一個實時更新的進度條的示例代碼

    本文詳細的介紹了SpringBoot如何實現(xiàn)一個實時更新的進度條,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • SpringBoot中配置文件及切換方式

    SpringBoot中配置文件及切換方式

    這篇文章主要介紹了SpringBoot中配置文件及切換方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • java基于jedisLock—redis分布式鎖實現(xiàn)示例代碼

    java基于jedisLock—redis分布式鎖實現(xiàn)示例代碼

    這篇文章主要介紹了jedisLock—redis分布式鎖實現(xiàn)示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • Java實現(xiàn)Token工具類進行登錄和攔截

    Java實現(xiàn)Token工具類進行登錄和攔截

    在應用的登錄時需要生成token進行驗證,并放入信息,之后的話可以直接使用瀏覽器的session進行登錄,本文就來利用java編寫一個token工具類,可以很方便的生成和解析token,感興趣的可以了解下
    2023-12-12
  • 如何解決Gradle、Maven項目build后沒有mybatis的mapper.xml文件的問題

    如何解決Gradle、Maven項目build后沒有mybatis的mapper.xml文件的問題

    這篇文章主要介紹了如何解決Gradle、Maven項目build后沒有mybatis的mapper.xml文件的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • java秒殺之redis限流操作詳解

    java秒殺之redis限流操作詳解

    這篇文章主要為大家詳細介紹了java秒殺之redis限流操作,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11

最新評論