最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot3中Spring?WebFlux?SSE服務(wù)器發(fā)送事件的實(shí)現(xiàn)步驟

 更新時(shí)間:2024年11月21日 14:12:28   作者:CoderJia  
本文介紹了如何使用SpringBoot3和響應(yīng)式編程實(shí)現(xiàn)服務(wù)器發(fā)送事件(SSE),并討論了其在實(shí)時(shí)數(shù)據(jù)推送場(chǎng)景中的優(yōu)勢(shì),通過(guò)示例代碼,展示了如何創(chuàng)建SSE控制器、客戶(hù)端接收數(shù)據(jù)以及優(yōu)化與擴(kuò)展,感興趣的朋友跟隨小編一起看看吧

ChatGPT 剛出的時(shí)候,讓大伙很好奇的是它是如何實(shí)現(xiàn)的逐字輸出的?答案就是 SSE (服務(wù)器發(fā)送事件)。隨著實(shí)時(shí)數(shù)據(jù)和響應(yīng)式編程的需求不斷增加,服務(wù)器發(fā)送事件(Server-Sent Events,簡(jiǎn)稱(chēng) SSE)在現(xiàn)代 Web 應(yīng)用程序中越來(lái)越受歡迎。SSE 提供了一種輕量級(jí)的服務(wù)器推送數(shù)據(jù)給客戶(hù)端的方式,適合用于監(jiān)控、實(shí)時(shí)通知、股票價(jià)格更新等場(chǎng)景。

在 Spring Boot 3 中,結(jié)合響應(yīng)式編程的理念,SSE 的實(shí)現(xiàn)變得更加簡(jiǎn)潔和高效。本文將詳細(xì)介紹如何使用 Spring Boot 3 來(lái)實(shí)現(xiàn) SSE 服務(wù)端推送,并討論響應(yīng)式編程在此過(guò)程中的重要性和優(yōu)勢(shì)。

1. 什么是 SSE?

服務(wù)器發(fā)送事件(SSE) 是一種從服務(wù)器向客戶(hù)端推送數(shù)據(jù)的技術(shù),屬于 HTML5 的一部分。與傳統(tǒng)的 HTTP 請(qǐng)求-響應(yīng)模型不同,SSE 是單向的,服務(wù)器可以持續(xù)不斷地向客戶(hù)端發(fā)送數(shù)據(jù),而客戶(hù)端通過(guò)一次長(zhǎng)連接持續(xù)接收這些更新。

相比 WebSocket,SSE 有以下特點(diǎn):

  • 單向通信:SSE 僅允許服務(wù)器向客戶(hù)端推送數(shù)據(jù),客戶(hù)端無(wú)法向服務(wù)器發(fā)送數(shù)據(jù)。
  • 基于 HTTP 協(xié)議:SSE 是建立在 HTTP 協(xié)議之上的,瀏覽器原生支持,不需要額外的協(xié)議處理。
  • 自動(dòng)重連:SSE 支持自動(dòng)重連,當(dāng)連接意外斷開(kāi)時(shí),客戶(hù)端會(huì)自動(dòng)嘗試重新連接服務(wù)器。

2. Spring Boot 3 響應(yīng)式編程與 SSE

Spring Boot 3 提供了對(duì)響應(yīng)式編程的全面支持,基于 Project Reactor 實(shí)現(xiàn)異步、非阻塞的流式數(shù)據(jù)處理。而響應(yīng)式編程非常適合實(shí)現(xiàn) SSE,因?yàn)樗试S我們以非阻塞的方式持續(xù)推送數(shù)據(jù),而不會(huì)阻塞服務(wù)器的資源。

Spring WebFlux 是 Spring Boot 3 中用于構(gòu)建響應(yīng)式應(yīng)用的核心框架,它可以無(wú)縫集成 SSE,為我們提供簡(jiǎn)單高效的服務(wù)器推送功能。

為什么選擇響應(yīng)式編程實(shí)現(xiàn) SSE?

傳統(tǒng)的阻塞式編程在處理長(zhǎng)連接(如 SSE)時(shí)可能會(huì)占用大量服務(wù)器資源。響應(yīng)式編程通過(guò)非阻塞 I/O 操作,不僅可以高效處理長(zhǎng)時(shí)間的連接,還能在有新數(shù)據(jù)時(shí)立即推送給客戶(hù)端。響應(yīng)式流(如 Flux)天然適合于這種流式數(shù)據(jù)推送場(chǎng)景。

3. 實(shí)現(xiàn) SSE 的基本步驟

我們將通過(guò)以下步驟實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 SSE 服務(wù)端推送應(yīng)用:

  • 創(chuàng)建 Spring Boot 項(xiàng)目并引入 WebFlux 依賴(lài)。
  • 實(shí)現(xiàn)服務(wù)端推送 SSE 事件流。
  • 編寫(xiě)客戶(hù)端接收 SSE 數(shù)據(jù)。
  • 測(cè)試與優(yōu)化。

3.1 創(chuàng)建 Spring Boot 項(xiàng)目

首先,創(chuàng)建一個(gè)新的 Spring Boot 3 項(xiàng)目,并確保引入了 spring-boot-starter-webflux 依賴(lài)??梢酝ㄟ^(guò) Maven 或 Gradle 配置:

Maven 依賴(lài)

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
</dependencies>

3.2 實(shí)現(xiàn)服務(wù)端推送SSE 事件流

在 Spring WebFlux 中,SSE 通過(guò)返回 Flux<ServerSentEvent<T>> 這種響應(yīng)流來(lái)實(shí)現(xiàn)。下面我們實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 SSE 控制器,它會(huì)每隔一段時(shí)間向客戶(hù)端推送當(dāng)前的時(shí)間信息。

示例控制器

package com.coderjia.boot3webflux.controller;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import reactor.core.publisher.Flux;
import java.time.Duration;
import java.time.LocalTime;
/**
 * @author CoderJia
 * @create 2024/10/27 下午 07:03
 * @Description
 **/
@Controller
public class SseController {
    @GetMapping("/sse/stream")
    public Flux<ServerSentEvent<String>> streamSse() {
        return Flux.interval(Duration.ofSeconds(1))
                .map(sequence -> ServerSentEvent.<String>builder()
                        .id(String.valueOf(sequence))
                        .event("periodic-event")
                        .data("Current time: " + LocalTime.now())
                        .build());
    }
}

解釋

Flux.interval(Duration.ofSeconds(1)):創(chuàng)建一個(gè)每秒發(fā)出事件的響應(yīng)式流。

ServerSentEvent.builder():構(gòu)建 ServerSentEvent 對(duì)象,它可以包含 id、eventdata 等信息,符合 SSE 規(guī)范。

map():將流中的每個(gè)事件映射為 ServerSentEvent,并附帶當(dāng)前的時(shí)間信息。

3.3 客戶(hù)端接收 SSE 數(shù)據(jù)

客戶(hù)端可以使用 JavaScript 原生的 EventSource API 來(lái)接收服務(wù)器發(fā)送的 SSE 數(shù)據(jù)流。

示例 HTML + JavaScript 客戶(hù)端

resources/static/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>SSE Example</title>
</head>
<body>
<h1>Server-Sent Events (SSE) Example</h1>
<div id="messages"></div>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
    const http = axios.create({
        baseURL: 'http://localhost:8080/',
        timeout: 100000,
        responseType: 'stream',
        onDownloadProgress: function (progressEvent) {
            // 獲取 messages 元素
            const messagesElement = document.getElementById("messages");
            // 清除現(xiàn)有內(nèi)容
            messagesElement.innerHTML = "";
            // 添加新內(nèi)容
            const newElement = document.createElement("div");
            newElement.innerHTML = progressEvent.event.currentTarget.responseText + "<br/>";
            messagesElement.appendChild(newElement);
        },
    });
    http.get('/sse/stream')
        .then(function (response) {
            // 處理成功情況
            console.log(response);
        })
        .catch(function (error) {
            // 處理錯(cuò)誤情況
            console.log(error);
        })
        .finally(function () {
            // 總是會(huì)執(zhí)行
        });
</script>
</body>
</html>

解釋

  • EventSource("/sse/stream"):EventSource 是瀏覽器提供的一個(gè)用于和服務(wù)器建立連接,接收服務(wù)器發(fā)送事件的接口。在客戶(hù)端發(fā)起與服務(wù)器的 SSE 長(zhǎng)連接。服務(wù)器通過(guò) /sse/stream 推送事件。
  • onmessage:處理服務(wù)器發(fā)送的消息,并將消息顯示在頁(yè)面上。
  • onerror:當(dāng)連接發(fā)生錯(cuò)誤時(shí)關(guān)閉連接,避免持續(xù)消耗資源。

4. 測(cè)試 SSE

運(yùn)行 Spring Boot 應(yīng)用,并訪問(wèn) /sse/stream,可以看到服務(wù)器每秒鐘向客戶(hù)端推送一次當(dāng)前時(shí)間信息。

接口請(qǐng)求

header 里的 Content-Type 為 text/event-stream。

Content-Type

可以通過(guò)瀏覽器打開(kāi) http://localhost:8080/,在頁(yè)面中將會(huì)每秒鐘顯示一次服務(wù)器推送的數(shù)據(jù)流。這就驗(yàn)證了 SSE 在 Spring Boot 3 中的實(shí)現(xiàn)。

瀏覽器展示

5. 優(yōu)化與擴(kuò)展

5.1 增加隨機(jī)數(shù)據(jù)推送

為了模擬更真實(shí)的場(chǎng)景,可以增加一些隨機(jī)數(shù)據(jù)或?qū)崟r(shí)數(shù)據(jù)更新。假設(shè)我們希望推送隨機(jī)的股票價(jià)格,我們可以這樣修改:

@GetMapping("/sse/stocks")
public Flux<ServerSentEvent<String>> streamStockPrices() {
    return Flux.interval(Duration.ofSeconds(1))
            .map(sequence -> ServerSentEvent.<String>builder()
                    .id(String.valueOf(sequence))
                    .event("stock-update")
                    .data("Stock price: $" + ThreadLocalRandom.current().nextInt(100, 200))
                    .build());
}

在這個(gè)例子中,每秒推送一次隨機(jī)的股票價(jià)格更新。

5.2 增加心跳檢測(cè)(Ping)

SSE 連接如果長(zhǎng)時(shí)間沒(méi)有數(shù)據(jù)傳輸,可能會(huì)被中斷。為此,SSE 規(guī)范推薦發(fā)送 “ping” 消息來(lái)保持連接活躍??梢酝ㄟ^(guò) ServerSentEventcomment() 來(lái)發(fā)送心跳信息:

@GetMapping("/sse/stream-with-ping")
public Flux<ServerSentEvent<String>> streamWithPing() {
    return Flux.interval(Duration.ofSeconds(1))
            .map(sequence -> {
                if (sequence % 5 == 0) {  // 每5秒發(fā)送一次心跳
                    return ServerSentEvent.<String>builder()
                            .comment("ping")
                            .build();
                } else {
                    return ServerSentEvent.<String>builder()
                            .data("Current time: " + LocalTime.now())
                            .build();
                }
            });
}

5.3 使用 MediaType.TEXT_EVENT_STREAM 響應(yīng)

雖然 ServerSentEvent 是處理 SSE 的標(biāo)準(zhǔn)類(lèi),但你也可以直接返回 Flux<T>,Spring 會(huì)自動(dòng)將其轉(zhuǎn)換為事件流。如果你想簡(jiǎn)化代碼,可以這樣寫(xiě):

@GetMapping(value = "/sse/simple", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> simpleSse() {
    return Flux.interval(Duration.ofSeconds(1))
            .map(sequence -> "Current time: " + LocalTime.now());
}

這里直接返回 Flux<String>,Spring WebFlux 會(huì)自動(dòng)推送數(shù)據(jù)。

6. SSE 與 WebSocket 的對(duì)比

SSE 和 WebSocket 都是實(shí)時(shí)通信的重要技術(shù),但它們有不同的適用場(chǎng)景:

  • SSE:?jiǎn)蜗蛲ㄐ?,服?wù)器推送數(shù)據(jù)到客戶(hù)端,適合輕量級(jí)的通知、監(jiān)控、消息更新等場(chǎng)景。使用簡(jiǎn)單,基于 HTTP。
  • WebSocket:雙向通信,適合復(fù)雜的交互場(chǎng)景,如實(shí)時(shí)聊天、在線(xiàn)游戲等。WebSocket 是基于 TCP 的全雙工連接,相對(duì)更復(fù)雜。

對(duì)于簡(jiǎn)單的實(shí)時(shí)更新場(chǎng)景,如股票價(jià)格更新、推送通知等,SSE 更加輕量且易于實(shí)現(xiàn)。

7. 總結(jié)

Spring Boot 3 提供了簡(jiǎn)單、強(qiáng)大的 SSE 實(shí)現(xiàn),結(jié)合響應(yīng)式編程的特性,使得我們可以輕松構(gòu)建高效的服務(wù)器推送應(yīng)用。在實(shí)際項(xiàng)目中,SSE 非常適合用于推送實(shí)時(shí)數(shù)據(jù)或監(jiān)控信息,尤其在需要輕量且可靠的單向通信時(shí)。通過(guò) Spring WebFlux 和 Project Reactor,SSE 的實(shí)現(xiàn)可以以非阻塞的方式運(yùn)行,極大提升了應(yīng)用的并發(fā)處理能力。

希望這篇博客對(duì)你理解 Spring Boot 3 中的 SSE 服務(wù)端推送有所幫助,如果有任何問(wèn)題或想法,歡迎討論!

到此這篇關(guān)于SpringBoot3中Spring WebFlux SSE服務(wù)器發(fā)送事件的實(shí)現(xiàn)步驟的文章就介紹到這了,更多相關(guān)SpringBoot SSE服務(wù)器發(fā)送事件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • fasterxml jackson反序列化時(shí)對(duì)于非靜態(tài)內(nèi)部類(lèi)報(bào)錯(cuò)問(wèn)題及解決

    fasterxml jackson反序列化時(shí)對(duì)于非靜態(tài)內(nèi)部類(lèi)報(bào)錯(cuò)問(wèn)題及解決

    這篇文章主要介紹了fasterxml jackson反序列化時(shí)對(duì)于非靜態(tài)內(nèi)部類(lèi)報(bào)錯(cuò)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • IntelliJ IDEA 中編寫(xiě) Speak 程序的詳細(xì)步驟和指南

    IntelliJ IDEA 中編寫(xiě) Speak 程序的詳細(xì)步驟和指南

    本文介紹了如何在IntelliJIDEA中編寫(xiě)一個(gè)語(yǔ)音交互程序,包括環(huán)境準(zhǔn)備、編寫(xiě)代碼、運(yùn)行和測(cè)試以及調(diào)試優(yōu)化,通過(guò)使用GoogleCloud的語(yǔ)音處理API,可以實(shí)現(xiàn)語(yǔ)音轉(zhuǎn)文本和文本轉(zhuǎn)語(yǔ)音功能,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • JAVA8 STREAM COLLECT GROUPBY分組實(shí)例解析

    JAVA8 STREAM COLLECT GROUPBY分組實(shí)例解析

    這篇文章主要介紹了JAVA8 STREAM COLLECT GROUPBY分組實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • java中用String.Join美化代碼的實(shí)例講解

    java中用String.Join美化代碼的實(shí)例講解

    在本篇文章里小編給大家整理的是一篇關(guān)于java中用String.Join美化代碼的實(shí)例講解內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。
    2020-12-12
  • Spring事務(wù)管理之如何處理刪除操作與事務(wù)回滾

    Spring事務(wù)管理之如何處理刪除操作與事務(wù)回滾

    在實(shí)際開(kāi)發(fā)中,事務(wù)管理是保證數(shù)據(jù)一致性的核心機(jī)制之一,本文將通過(guò)一個(gè)實(shí)際案例,詳細(xì)分析Spring事務(wù)中的刪除操作與回滾機(jī)制,并提供優(yōu)化方案,需要的可以參考下
    2025-04-04
  • 求最大子數(shù)組之和的方法解析(2種可選)

    求最大子數(shù)組之和的方法解析(2種可選)

    本文主要對(duì)求最大子數(shù)組之和的方法進(jìn)行詳細(xì)解析,列了兩種方法供大家選擇借鑒,需要的朋友一起來(lái)看下吧
    2016-12-12
  • 如何使用spring?boot的程序主線(xiàn)程中異步訪問(wèn)外部接口

    如何使用spring?boot的程序主線(xiàn)程中異步訪問(wèn)外部接口

    CompletableFuture.supplyAsync提供了一種強(qiáng)大的工具,使您能夠以異步方式執(zhí)行操作,充分利用多核處理器和提高程序性能,同時(shí)保持代碼的清晰性和可維護(hù)性,本文給大家介紹使用spring?boot的程序主線(xiàn)程中異步訪問(wèn)外部接口,感興趣的朋友一起看看吧
    2023-10-10
  • JavaMe開(kāi)發(fā)自適應(yīng)滾動(dòng)顯示

    JavaMe開(kāi)發(fā)自適應(yīng)滾動(dòng)顯示

    我們??吹揭恍L動(dòng)顯示的實(shí)例,比如UC瀏覽器中,顯示網(wǎng)頁(yè)的內(nèi)容。當(dāng)內(nèi)容比較多時(shí),采用滾動(dòng)分頁(yè)顯示是合理的。在Canvas中繪圖中,多余的內(nèi)容被截?cái)嗔?。如何?shí)現(xiàn)滾動(dòng)分頁(yè)顯示呢?
    2015-09-09
  • java多態(tài)中的就近原則介紹

    java多態(tài)中的就近原則介紹

    大家好,本篇文章主要講的是java多態(tài)中的就近原則介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話(huà)記得收藏一下,方便下次瀏覽
    2021-12-12
  • Java使用JNA調(diào)用DLL文件

    Java使用JNA調(diào)用DLL文件

    JNA(Java?Native?Access)是一個(gè)在?Java?中調(diào)用本地代碼的開(kāi)源框架,提供了一種簡(jiǎn)單、高效的方式來(lái)訪問(wèn)本地動(dòng)態(tài)鏈接庫(kù),下面我們來(lái)看看Java如何使用JNA調(diào)用DLL文件吧
    2024-12-12

最新評(píng)論

伽师县| 泰州市| 烟台市| 蒙自县| 同仁县| 息烽县| 图木舒克市| 佛冈县| 广元市| 吐鲁番市| 顺义区| 疏勒县| 墨脱县| 始兴县| 湖南省| 榆社县| 泸水县| 措美县| 纳雍县| 禹城市| 诏安县| 榆中县| 蓝田县| 全椒县| 和政县| 大荔县| 临泉县| 玛沁县| 宁德市| 庆阳市| 兴文县| 乌拉特中旗| 遵化市| 横峰县| 潞西市| 柳江县| 兴海县| 天台县| 类乌齐县| 滁州市| 洞口县|