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

springboot+vue實現(xiàn)SSE服務(wù)器發(fā)送事件的示例

 更新時間:2025年01月02日 09:06:02   作者:black^sugar  
本文介紹了使用Spring Boot和Vue實現(xiàn)服務(wù)器發(fā)送事件,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

思路

一個基于訂閱發(fā)布機制的SSE事件。客戶端可以請求訂閱api(攜帶客戶端id),與服務(wù)器建立SSE鏈接;后續(xù)服務(wù)器需要推送消息到客戶端時,再根據(jù)客戶端id從已建立鏈接的會話中找到目標客戶端,將消息推送出去。

后端

這個控制器類允許客戶端訂閱、接收消息和斷開連接,通過 pool 存儲 SseEmitter 并對其進行管理。

package com.example.q11e.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

@RestController
public class SseController {
    // 存儲已訂閱的客戶端的會話列表
    private final Map<String, SseEmitter> pool = new ConcurrentHashMap<>();

    // 向特定的 SseEmitter 發(fā)送消息
    public void publisher(String id_sid, int content) {
        // 根據(jù) id_sid 從映射中獲取 SseEmitter
        SseEmitter sseEmitter = pool.get(id_sid);
        if (Objects.isNull(sseEmitter)) {
            return;
        }
        try {
            sseEmitter.send(content); // 發(fā)送內(nèi)容
        } catch (IOException e) {
            System.out.println("null " + e);
        }
    }


    // 處理客戶端的訂閱請求
    @GetMapping("/subscribe/{id}")
    public SseEmitter subscribe(@PathVariable("id") String id_sid) {
        // 根據(jù) id_sid 從映射中獲取 SseEmitter
        SseEmitter sseEmitter = pool.get(id_sid);
        if (Objects.isNull(sseEmitter)) {
            // 如果不存在,則創(chuàng)建一個新的 SseEmitter,設(shè)置超時時間為 130000 毫秒
            sseEmitter = new SseEmitter(130000L);
            // 設(shè)置發(fā)送完成事件:從映射中移除該 SseEmitter
            sseEmitter.onCompletion(() -> pool.remove(id_sid)); 
            // 設(shè)置超時事件:從映射中移除該 SseEmitter
            sseEmitter.onTimeout((() -> pool.remove(id_sid))); 
            // 將新創(chuàng)建的 SseEmitter 放入映射中
            pool.put(id_sid, sseEmitter);
        }
        // System.out.println(pool);
        // 返回 SseEmitter 給客戶端
        return sseEmitter;
    }

    // 處理客戶端的斷開連接請求
    public void disconnect(String id_sid) {
        SseEmitter emitter = pool.remove(id_sid);
        if (emitter!= null) {
            emitter.complete();
        }
    }
}

發(fā)送消息

package com.example.q11e.service;

import com.example.q11e.controller.SseController;

@Service
public class BatchService {
    @Autowired
    public BatchService(SseController sseController) {
        this.sseController = sseController;
    }
    private final SseController sseController;

    @Async
    public void batchRequests(){
        // uid+"_"+sid 客戶端標識符,sucCount為需要發(fā)送的信息
        sseController.publisher(uid + "_" + sid, sucCount);
        sseController.disconnect(uid + "_" + sid);
    }
}

前端

SSE狀態(tài)管理  store.ts

// sse前端
import { defineStore } from 'pinia';
import { getUserBalance } from '@/request/api.ts'

export const useESStore = defineStore('EventSource', {
  state: () => ({
    uid: localStorage.getItem('uid'),
    balance: 1,
    eventSourceInstance: null as EventSource | null, // 新增狀態(tài)屬性
    currentSid: null as string | null,
    currentCount: 0,
    currentTotal: 0,
    connect: false
  }),
  actions: {
    setUid(uid:string) {
      this.uid = uid;
    },
    setConnect(connect: boolean) {
      this.connect = connect
    },
    initEventSource(sid:string) {
      if (this.uid) {
        const sseURL = import.meta.env.VITE_SSE_URL
        const evtSrcInstance = new EventSource(sseURL + "/" + this.uid + "_" + sid);
        evtSrcInstance.onmessage = (e) => {
          this.setCurrentCount(e.data) //普通函數(shù)時: this-->evtSrcInstance
        };
        evtSrcInstance.onopen = () => {
          this.setCurrentCount(0)
          this.setConnect(true)
        };
        evtSrcInstance.onerror = () => {
          this.setConnect(false)
          this.setCurrentTotal(0)
        };
        this.eventSourceInstance = evtSrcInstance; // 存儲實例到狀態(tài)
      }
    },
    closeEventSource() {
      if (this.eventSourceInstance) {
        this.eventSourceInstance.close();
        this.eventSourceInstance = null;
      }
    }
  }
});
<template>
  <span v-show="connect">
    <span class="sid">{{ sid }}</span>
    <span v-for="(char, index) in ['.', '.', '.']" :key="index" class="blink-effect sid"
      :style="{ animationDelay: `${index * 0.1}s` }">{{ char }}</span>
     <!----count是服務(wù)器推送的內(nèi)容----->
    <span class="process">{{ count }}/{{ total }}</span>
  </span>
</template>

<script lang="ts" setup>
import { computed } from 'vue'
import { useESStore } from '@/store/store.ts'
const SSE = useESStore()
let count = computed(() => SSE.currentCount)
let total = computed(() => SSE.currentTotal)
let sid = computed(() => SSE.currentSid)
let connect = computed(() => SSE.connect)
</script>

<style scoped>
.process {
  background: red;
  color: white;
  padding: 2px 4px;
}
.sid { color: #333; }
@keyframes blink {
  0%, 100% {
    transform: translateY(0); /* 開始和結(jié)束狀態(tài)位置無變化 */
  }
  50% {
    transform: translateY(-5px); /* 中間狀態(tài)位置向上移動5px */
  }
}
.blink-effect {
  display: inline-block;
  animation: blink 1s infinite;
}
</style>

效果

后端執(zhí)行某耗時任務(wù)時,需要實時推送進度到客戶端,每完成一個階段,就向客戶端推送一個單位進度,做到客戶端實時顯示進度的效果。

到此這篇關(guān)于springboot+vue實現(xiàn)SSE服務(wù)器發(fā)送事件的示例的文章就介紹到這了,更多相關(guān)springboot vue SSE發(fā)送事件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaWeb讀取配置文件的四種方法

    JavaWeb讀取配置文件的四種方法

    這篇文章主要介紹了JavaWeb讀取配置文件的4種方法,方法一采用ServletContext讀取,方法二采用ResourceBundle類讀取配置信息,方法三采用ClassLoader方式進行讀取配置信息,對javaweb讀取配置文件的四種方法感興趣的朋友參考下吧
    2018-03-03
  • 詳解Java設(shè)計模式編程中的策略模式

    詳解Java設(shè)計模式編程中的策略模式

    這篇文章主要介紹了詳解Java設(shè)計模式編程中的策略模式,策略模式強調(diào)對對象的封裝使用,比如文中舉的錦囊妙計的例子便很生動,需要的朋友可以參考下
    2016-02-02
  • Spring Boot 將yyyy-MM-dd格式的文本字符串直接轉(zhuǎn)換為LocalDateTime出現(xiàn)的問題

    Spring Boot 將yyyy-MM-dd格式的文本字符串直接轉(zhuǎn)換為LocalDateTime出現(xiàn)的問題

    這篇文章主要介紹了Spring Boot 將yyyy-MM-dd格式的文本字符串直接轉(zhuǎn)換為LocalDateTime出現(xiàn)的問題,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Java 詳解異常的處理機制

    Java 詳解異常的處理機制

    異常是程序中的一些錯誤,但并不是所有的錯誤都是異常,并且錯誤有時候是可以避免的。比如你的代碼少一個分號,那運行出來結(jié)果是提示是錯誤 java.lang.Error;如果你用System.out.println(11/0),那你是因為用0做了除數(shù),會拋出 java.lang.ArithmeticException 的異常
    2021-11-11
  • Java DriverManager.getConnection()獲取數(shù)據(jù)庫連接

    Java DriverManager.getConnection()獲取數(shù)據(jù)庫連接

    這篇文章主要介紹了Java DriverManager.getConnection()獲取數(shù)據(jù)庫連接,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • SpringSecurity實現(xiàn)圖形驗證碼功能的實例代碼

    SpringSecurity實現(xiàn)圖形驗證碼功能的實例代碼

    Spring Security 的前身是 Acegi Security ,是 Spring 項目組中用來提供安全認證服務(wù)的框架。這篇文章主要介紹了SpringSecurity實現(xiàn)圖形驗證碼功能,需要的朋友可以參考下
    2018-10-10
  • SpringBoot整合mybatis常見問題(小結(jié))

    SpringBoot整合mybatis常見問題(小結(jié))

    這篇文章主要介紹了SpringBoot整合mybatis常見問題(小結(jié)),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • java控制臺輸入示例分享

    java控制臺輸入示例分享

    這篇文章主要介紹了java控制臺輸入示例分享,需要的朋友可以參考下
    2014-03-03
  • SpringCloud之注冊中心之Nacos負載均衡詳解

    SpringCloud之注冊中心之Nacos負載均衡詳解

    Nacos提供多種負載均衡策略,包括權(quán)重、同機房、同地域、同環(huán)境等,服務(wù)下線和權(quán)重配置可以通過Nacos管理界面進行,同時,Nacos使用Raft算法選舉Leader節(jié)點,若IP地址改變可能會影響Leader選舉,配置同集群優(yōu)先訪問可以提高訪問速度,通過配置集群名稱和負載均衡策略
    2025-03-03
  • springboot整合Atomikos的示例詳解

    springboot整合Atomikos的示例詳解

    這篇文章主要為大家詳細介紹了幾種分布式事務(wù)的解決方案的兩階段提交Atomikos,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下
    2024-11-11

最新評論