SSE Emitter在Spring Boot和Vue中的简单使用

1、确保你的 pom.xml 包含 Spring Web 依赖

XML 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2、创建 SSE 控制器

java 复制代码
package com.keran.wms.controller;

import cn.hutool.json.JSONObject;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.concurrent.*;

@RestController
@RequestMapping("/sse")
public class SseController {

    private final CopyOnWriteArrayList<SseEmitter> emitters = new CopyOnWriteArrayList<>();

    // 客户端连接端点
    @GetMapping(path = "/connect")
    public SseEmitter connect() {
        SseEmitter emitter = new SseEmitter(60_000L); // 超时时间60秒

        emitter.onCompletion(() -> emitters.remove(emitter));
        emitter.onTimeout(() -> emitters.remove(emitter));

        emitters.add(emitter);

        return emitter;
    }

    // 向所有客户端发送消息
    public void sendEventToAll(String data) {
        for (SseEmitter emitter : emitters) {
            try {
                emitter.send(SseEmitter.event()
                        .data(data)
                        .name("message")); // 事件名称
            } catch (IOException e) {
                emitter.complete();
                emitters.remove(emitter);
            }
        }
    }

    // 测试发送消息的端点
    @GetMapping("/send")
    public JSONObject sendMessage() {
        sendEventToAll("Server time: " + System.currentTimeMillis());
        return new JSONObject().set("status", "Message sent to all clients");
    }

    // 每20秒发送一次心跳
    @Scheduled(fixedRate = 20000)
    public void sendHeartbeat() {
        emitters.forEach(emitter -> {
            try {
                emitter.send(SseEmitter.event()
                        .data("heartbeat")
                        .reconnectTime(5000L)); // 建议的重连时间
            } catch (IOException e) {
                emitter.completeWithError(e);
                emitters.remove(emitter);
            }
        });
    }

}

3、前端Vue实现

html 复制代码
<template>
  <div>
    <h1>SSE Demo</h1>
    <div v-for="(message, index) in messages" :key="index">
      {{ message }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      messages: [],
      eventSource: null,
      reconnectDelay: 5000,
    };
  },
  mounted() {
    this.connectSSE();
  },
  beforeDestroy() {
    if (this.eventSource) {
      this.eventSource.close();
    }
  },
  methods: {
    connectSSE() {
      // 替换为你的Spring Boot后端地址
      this.eventSource = new EventSource('http://localhost:8080/sse/connect');
      
      // 通用消息处理器
      this.eventSource.onmessage = (event) => {
        this.messages.push(event.data);
      };
      
      // 特定事件处理器(对应后端.name()设置的事件名)
      this.eventSource.addEventListener('message', (event) => {
        this.messages.push(event.data);
      });
      
      // 错误处理
      this.eventSource.onerror = (error) => {
        this.eventSource.close();
        if (this.reconnectAttempts < this.maxReconnectAttempts) {
            setTimeout(() => {
            this.reconnectAttempts++;
            this.connectSSE();
        }, this.reconnectDelay);
      }
      };
    }
  }
};
</script>

4、访问 http://localhost:6065/sse/send测试

5、测试成功

相关推荐
小小小小宇13 分钟前
Pi 手动添加
前端
vipxieliang20 分钟前
ValidX vs Apache Commons Validator:功能与性能对比
java·spring boot
然我25 分钟前
模型不是 Agent:从零实现一个最小 Agent Loop
前端·人工智能·agent
boooooooom32 分钟前
手把手做一个图 RAG 烹饪问答系统:Neo4j + Milvus + LLM 的工程实践
前端·javascript·后端
小小善后师33 分钟前
HID 设备对接技术解析:基于本地中间服务的 WebSocket 通信模式
前端
黄油面包35 分钟前
Codex 额度三天见底后,我重新做了一周预算
前端·人工智能
PedroQue9938 分钟前
v2.7.1:修复 H5 端返回死循环闪烁问题
前端·uni-app
coderCN39 分钟前
Nodejs express+knex(ORM框架)
前端·node.js
求道於盲43 分钟前
python中的抽象类
前端
吃饱了得干活1 小时前
一篇讲清楚Spring Boot:自动装配、启动器、过滤器、拦截器、设计模式
java·spring boot·后端