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

Spring 框架中的 SseEmitter 使用原理解析

 更新時(shí)間:2026年02月10日 10:52:59   作者:sg_knight  
SseEmitter是Spring MVC提供的一個(gè)類(lèi),用于實(shí)現(xiàn)基于HTTP的服務(wù)器單向推送(Server-Sent Events),本文給大家介紹Spring框架中的 SseEmitter使用詳解,感興趣的朋友跟隨小編一起看看吧

       在需要實(shí)時(shí)向前端推送數(shù)據(jù)時(shí),很多人第一反應(yīng)是 WebSocket。但如果你的需求是“服務(wù)端單向推送”,并不需要客戶(hù)端向后端發(fā)送消息,那么 Spring 提供的 SseEmitter 會(huì)更加輕量、更易用,而且天然支持?jǐn)嗑€重連。本文總結(jié)了 SseEmitter 的核心原理、常見(jiàn)用法、注意事項(xiàng)以及生產(chǎn)實(shí)踐經(jīng)驗(yàn)。

一、SseEmitter 是什么?

SseEmitter 是 Spring MVC 提供的一個(gè)類(lèi),用于實(shí)現(xiàn) 基于 HTTP 的服務(wù)器單向推送(Server-Sent Events)。

它的特點(diǎn)包括:

  • 單向推送(服務(wù)端 → 客戶(hù)端)
  • 基于標(biāo)準(zhǔn) HTTP(不需要新協(xié)議)
  • 支持自動(dòng)重連(瀏覽器 EventSource 自帶)
  • 使用簡(jiǎn)單比 WebSocket 更輕,更適合消息通知類(lèi)業(yè)務(wù)

適用場(chǎng)景:

  • 消息提醒
  • 實(shí)時(shí)狀態(tài)更新
  • 任務(wù)進(jìn)度推送
  • 監(jiān)控?cái)?shù)據(jù)刷新

二、基礎(chǔ)用法示例

1. 創(chuàng)建 SSE 連接接口

@GetMapping("/sse/connect")
public SseEmitter connect() {
    SseEmitter emitter = new SseEmitter(0L); // 0 表示不過(guò)期
    // 在連接時(shí)發(fā)送一條消息
    try {
        emitter.send("連接成功");
    } catch (Exception e) {
        emitter.completeWithError(e);
    }
    return emitter;
}

注意:

  • new SseEmitter(0L) 表示不超時(shí),可減少長(zhǎng)連接斷開(kāi)問(wèn)題。
  • 返回后客戶(hù)端會(huì)進(jìn)入持續(xù)接收狀態(tài)。

三、服務(wù)端主動(dòng)推送消息

@Autowired
private List<SseEmitter> emitters = new CopyOnWriteArrayList<>();
@GetMapping("/sse/connect")
public SseEmitter connect() {
    SseEmitter emitter = new SseEmitter(0L);
    emitters.add(emitter);
    emitter.onCompletion(() -> emitters.remove(emitter));
    emitter.onTimeout(() -> emitters.remove(emitter));
    return emitter;
}
@PostMapping("/sse/send")
public void sendMessage(@RequestParam String msg) {
    for (SseEmitter emitter : emitters) {
        try {
            emitter.send(msg);
        } catch (Exception e) {
            emitter.complete();
        }
    }
}

關(guān)鍵點(diǎn):

  • 使用 CopyOnWriteArrayList 保存所有連接
  • 斷開(kāi)/異常時(shí)及時(shí)清理 emitter
  • 推送時(shí)遍歷所有 emitter

四、前端(瀏覽器)接收實(shí)現(xiàn)

const evtSource = new EventSource("/sse/connect");
evtSource.onmessage = function (event) {
    console.log("收到消息:", event.data);
};

瀏覽器自帶特性:斷線自動(dòng)重連,不需要你自己實(shí)現(xiàn)。

五、常見(jiàn)問(wèn)題與解決方案

1.前端收不到消息?(最常見(jiàn))

原因可能是:

  • 沒(méi)有使用 UTF-8 文本格式
  • 推送內(nèi)容太大或太快
  • 連接被代理/網(wǎng)關(guān)斷開(kāi)

解決:

emitter.send(SseEmitter.event().data("內(nèi)容").id("1").name("msg"));

2.Nginx 或網(wǎng)關(guān) 1 分鐘斷開(kāi)

這是行業(yè)常見(jiàn)問(wèn)題,需要配置:

proxy_read_timeout 3600;
proxy_send_timeout 3600;

3.Spring 默認(rèn)超時(shí)導(dǎo)致斷開(kāi)

務(wù)必使用:

new SseEmitter(0L);

4.消息推送異常導(dǎo)致連接中斷

一定要在異常時(shí)清理 emitter:

catch (Exception e) {
    emitter.completeWithError(e);
}

六、生產(chǎn)實(shí)踐建議

  • 使用 心跳包 防止代理斷開(kāi)(比如每 20 秒發(fā)送一次空事件)
  • 使用 CopyOnWriteArrayList 或 ConcurrentHashMap 存儲(chǔ)用戶(hù)連接
  • 對(duì)每個(gè)發(fā)送操作包一層 try/catch,避免單個(gè)連接阻塞所有推送
  • 數(shù)據(jù)頻繁更新建議加上消息合并策略,避免推太快導(dǎo)致阻塞

總結(jié)

SseEmitter 是一個(gè)輕量但功能強(qiáng)大的實(shí)時(shí)推送工具,特別適合實(shí)時(shí)通知類(lèi)業(yè)務(wù)。相比 WebSocket,它更簡(jiǎn)單,不需要復(fù)雜協(xié)議和框架即可實(shí)現(xiàn)穩(wěn)定的實(shí)時(shí)消息推送。

如果你的業(yè)務(wù)屬于“服務(wù)端單向推送”,SseEmitter 往往是最優(yōu)選擇。

到此這篇關(guān)于Spring 框架中的 SseEmitter 使用原理解析的文章就介紹到這了,更多相關(guān)Spring SseEmitter 使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

原平市| 郴州市| 常德市| 神木县| 星子县| 吉林省| 中卫市| 邛崃市| 滕州市| 高雄市| 桂东县| 平山县| 防城港市| 泰宁县| 大名县| 沁阳市| 华容县| 米林县| 新郑市| 河曲县| 五莲县| 霸州市| 稻城县| 太保市| 无极县| 大冶市| 丹寨县| 青州市| 慈利县| 八宿县| 油尖旺区| 靖西县| 博白县| 镇安县| 榆林市| 祁门县| 广饶县| 上饶市| 思茅市| 旅游| 金乡县|