欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring Boot中使用Server-Sent Events (SSE) 實現(xiàn)實時數(shù)據(jù)推送教程

 更新時間:2024年03月29日 09:12:21   作者:冬山兄  
Server-Sent Events (SSE) 是HTML5引入的一種輕量級的服務器向瀏覽器客戶端單向推送實時數(shù)據(jù)的技術(shù),本文主要介紹了Spring Boot中使用Server-Sent Events (SSE) 實現(xiàn)實時數(shù)據(jù)推送教程,具有一定的參考價值,感興趣的可以了解一下

一、簡介

Server-Sent Events (SSE) 是HTML5引入的一種輕量級的服務器向瀏覽器客戶端單向推送實時數(shù)據(jù)的技術(shù)。在Spring Boot框架中,我們可以很容易地集成并利用SSE來實現(xiàn)實時通信。

二、依賴添加

在Spring Boot項目中,無需額外引入特定的依賴,因為Spring Web MVC模塊已經(jīng)內(nèi)置了對SSE的支持。

輔助Maven

        <!-- 集成beetl -->
        <dependency>
            <groupId>com.ibeetl</groupId>
            <artifactId>beetl-framework-starter</artifactId>
            <version>1.2.30.RELEASE</version>
        </dependency>

        <!-- 集成hutool工具類簡便操作 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.3.10</version>
        </dependency>

三、編寫核心SSE Client

@Slf4j
@Component
public class SseClient {
    private static final Map<String, SseEmitter> sseEmitterMap = new ConcurrentHashMap<>();
    /**
     * 創(chuàng)建連接
     */
    public SseEmitter createSse(String uid) {
        //默認30秒超時,設置為0L則永不超時
        SseEmitter sseEmitter = new SseEmitter(0l);
        //完成后回調(diào)
        sseEmitter.onCompletion(() -> {
            log.info("[{}]結(jié)束連接...................", uid);
            sseEmitterMap.remove(uid);
        });
        //超時回調(diào)
        sseEmitter.onTimeout(() -> {
            log.info("[{}]連接超時...................", uid);
        });
        //異?;卣{(diào)
        sseEmitter.onError(
                throwable -> {
                    try {
                        log.info("[{}]連接異常,{}", uid, throwable.toString());
                        sseEmitter.send(SseEmitter.event()
                                .id(uid)
                                .name("發(fā)生異常!")
                                .data("發(fā)生異常請重試!")
                                .reconnectTime(3000));
                        sseEmitterMap.put(uid, sseEmitter);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
        );
        try {
            sseEmitter.send(SseEmitter.event().reconnectTime(5000));
        } catch (IOException e) {
            e.printStackTrace();
        }
        sseEmitterMap.put(uid, sseEmitter);
        log.info("[{}]創(chuàng)建sse連接成功!", uid);
        return sseEmitter;
    }

    /**
     * 給指定用戶發(fā)送消息
     *
     */
    public boolean sendMessage(String uid,String messageId, String message) {
        if (StrUtil.isBlank(message)) {
            log.info("參數(shù)異常,msg為null", uid);
            return false;
        }
        SseEmitter sseEmitter = sseEmitterMap.get(uid);
        if (sseEmitter == null) {
            log.info("消息推送失敗uid:[{}],沒有創(chuàng)建連接,請重試。", uid);
            return false;
        }
        try {
            sseEmitter.send(SseEmitter.event().id(messageId).reconnectTime(1*60*1000L).data(message));
            log.info("用戶{},消息id:{},推送成功:{}", uid,messageId, message);
            return true;
        }catch (Exception e) {
            sseEmitterMap.remove(uid);
            log.info("用戶{},消息id:{},推送異常:{}", uid,messageId, e.getMessage());
            sseEmitter.complete();
            return false;
        }
    }

    /**
     * 斷開
     * @param uid
     */
    public void closeSse(String uid){
        if (sseEmitterMap.containsKey(uid)) {
            SseEmitter sseEmitter = sseEmitterMap.get(uid);
            sseEmitter.complete();
            sseEmitterMap.remove(uid);
        }else {
            log.info("用戶{} 連接已關(guān)閉",uid);
        }

    }

}
  • 創(chuàng)建SSE 端點:創(chuàng)建一個SseEmitter,用uid進行標識,uid可以是用戶標識符,也可以是業(yè)務標識符??梢岳斫鉃橥ㄐ判诺罉俗R。
  • 通過端點發(fā)送事件:可以定時或在事件發(fā)生時調(diào)用sseEmitter.send()方法來發(fā)送事件。
  • 關(guān)閉端點連接

四、編寫Controller

@Controller
public class IndexAction {
    @Autowired
    private SseClient sseClient;
    @GetMapping("/")
    public String index(ModelMap model) {
        String uid = IdUtil.fastUUID();
        model.put("uid",uid);
        return "index";
    }

    @CrossOrigin
    @GetMapping("/createSse")
    public SseEmitter createConnect(String uid) {
        return sseClient.createSse(uid);
    }
    @CrossOrigin
    @GetMapping("/sendMsg")
    @ResponseBody
    public String sseChat(String uid) {
        for (int i = 0; i < 10; i++) {
            sseClient.sendMessage(uid, "no"+i,IdUtil.fastUUID());
        }
        return "ok";
    }

    /**
     * 關(guān)閉連接
     */
    @CrossOrigin
    @GetMapping("/closeSse")
    public void closeConnect(String uid ){

        sseClient.closeSse(uid);
    }
}

1,打開頁面默認頁面,傳遞端點標識。

2,連接端點(/createSse),頁面需要使用

3,通過ajax(/sendMsg),觸發(fā)后端業(yè)務(循環(huán)十條數(shù)據(jù)發(fā)往頁面),向頁面發(fā)送消息。

4,主動關(guān)閉連接(/closeSse)

五、前端接收與處理

HTML & JavaScript

在前端頁面,使用EventSource API訂閱SSE endpoint:

Html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="con"></div>
<script>
    let chat = document.getElementById("con");
    if (window.EventSource) {
        //創(chuàng)建sse
         eventSource = new EventSource(`/createSse?uid=${uid}`);
        eventSource.onopen = function (event) {
            console.log('SSE鏈接成功');
        }
        eventSource.onmessage = function (event) {
            if(event.data){
                chat.innerHTML += event.data + '<br/>';
                //console.log('后端返回的數(shù)據(jù):', data.value);
            }
        }
        eventSource.onerror = (error) => {
            console.log('SSE鏈接失敗');
        };
    } else {
        alert("你的瀏覽器不支持SSE");
    }
</script>
</body>
</html>

在這個例子中,前端每接收到一次SSE推送的事件,就會在id為"con"的元素中追加數(shù)據(jù)。

六、注意事項

  • 當客戶端斷開連接時,SseEmitter會拋出IOException,所以務必捕獲并處理這種異常,通常情況下我們會調(diào)用emitter.complete()emitter.completeWithError()來關(guān)閉SseEmitter。
  • SSE連接是持久性的,長時間保持連接可能需要處理超時和重連問題。
  • 考慮到資源消耗,對于大量的并發(fā)客戶端,可能需要采用連接池或者其他優(yōu)化策略。

總結(jié),Spring Boot中利用SSE實現(xiàn)實時數(shù)據(jù)推送既簡單又實用,特別適合實時更新頻率不高、實時性要求不嚴苛的場景。同時,在高并發(fā)場景下需要注意資源管理和優(yōu)化策略的選擇。

到此這篇關(guān)于Spring Boot中使用Server-Sent Events (SSE) 實現(xiàn)實時數(shù)據(jù)推送教程的文章就介紹到這了,更多相關(guān)SpringBoot 實時數(shù)據(jù)推送內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java插件擴展機制之SPI案例講解

    Java插件擴展機制之SPI案例講解

    這篇文章主要介紹了Java插件擴展機制之SPI案例講解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 關(guān)于Java中的可見性和有序性問題

    關(guān)于Java中的可見性和有序性問題

    這篇文章主要介紹了關(guān)于Java中的可見性和有序性問題,Java在誕生之初就支持多線程,自然也有針對這三者的技術(shù)方案,今天就學習一下Java如何解決其中的可見性和有序性導致的問題,需要的朋友可以參考下
    2023-08-08
  • 解決mybatis-plus 查詢耗時慢的問題

    解決mybatis-plus 查詢耗時慢的問題

    這篇文章主要介紹了解決mybatis-plus 查詢耗時慢的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Spring-boot 中@Async使用遇到的坑

    Spring-boot 中@Async使用遇到的坑

    這篇文章主要介紹了Spring-boot 中@Async使用的坑,首先使用@Async 需要在Spring啟動類上添加注解@EnableAsyn或者在你們線程池配置類添加@EnableAsyn,需要的朋友可以參考下
    2024-01-01
  • MyBatis?超詳細講解動態(tài)SQL的實現(xiàn)

    MyBatis?超詳細講解動態(tài)SQL的實現(xiàn)

    動態(tài)?SQL?是?MyBatis?的強大特性之一。如果你使用過?JDBC?或其它類似的框架,你應該能理解根據(jù)不同條件拼接?SQL?語句有多痛苦,例如拼接時要確保不能忘記添加必要的空格,還要注意去掉列表最后一個列名的逗號。利用動態(tài)?SQL,可以徹底擺脫這種痛苦
    2022-03-03
  • Java中的RPC框架Dubbo原理和機制詳解

    Java中的RPC框架Dubbo原理和機制詳解

    這篇文章主要介紹了Java中的RPC框架Dubbo原理和機制詳解,Dubbo 是一款Java RPC框架,致力于提供高性能的 RPC 遠程服務調(diào)用方案,作為主流的微服務框架之一,Dubbo 為開發(fā)人員帶來了非常多的便利,需要的朋友可以參考下
    2024-01-01
  • 詳解Spring Boot對 Apache Pulsar的支持

    詳解Spring Boot對 Apache Pulsar的支持

    Spring Boot通過提供spring-pulsar和spring-pulsar-reactive自動配置支持Apache Pulsar,類路徑中這些依賴存在時,Spring Boot自動配置命令式和反應式Pulsar組件,PulsarClient自動注冊,默認連接本地Pulsar實例,感興趣的朋友一起看看吧
    2024-11-11
  • Java中的Sentinel持久化規(guī)則啟動

    Java中的Sentinel持久化規(guī)則啟動

    這篇文章主要介紹了Java中的Sentinel持久化規(guī)則啟動,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • Spring Boot中使用Actuator的/info端點輸出Git版本信息

    Spring Boot中使用Actuator的/info端點輸出Git版本信息

    這篇文章主要介紹了Spring Boot中使用Actuator的/info端點輸出Git版本信息,需要的朋友可以參考下
    2017-06-06
  • Java 14 發(fā)布了,你還會使用Lombok?

    Java 14 發(fā)布了,你還會使用Lombok?

    2020年3月17日發(fā)布,Java正式發(fā)布了JDK 14 ,目前已經(jīng)可以開放下載。在JDK 14中,共有16個新特性,本文主要來介紹其中的一個特性:JEP 359: Records,需要的朋友可以參考下
    2020-04-04

最新評論