轻松实现服务器事件主动推送到web端!Spring SseEmitter 详解

SseEmitter 是 Spring Framework 中用于服务器发送事件(Server-Sent Events, SSE)的类。SSE 是一种允许服务器推送更新到客户端的技术,通常用于实时更新的场景,如股票价格、实时消息、游戏状态等,又或者想要实现像ChatGPT那样的流式问答的效果。

以下是 SseEmitter 的一些关键点和使用方法:

关键点

  1. 服务器推送事件:与 WebSocket 不同,SSE 是单向通信,从服务器到客户端。客户端通过 HTTP 请求订阅事件,服务器在事件发生时推送数据。
  2. 基于 HTTP 协议:SSE 使用 HTTP 协议,客户端通过标准的 HTTP 请求订阅,服务器通过 HTTP 响应推送事件。
  3. 自动重连:大多数浏览器内置对 SSE 的支持,并且会在连接断开时自动尝试重新连接。
  4. 简单性:SSE 相对于 WebSocket 更加简单和轻量,适用于只需要服务器向客户端推送数据的应用场景。

使用方法

1. 添加依赖

确保你的项目中包含 Spring Web 依赖。

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
2. 创建控制器

创建一个 REST 控制器来处理 SSE 请求。

java 复制代码
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@RestController
public class SseController {

    @GetMapping("/sse")
    public SseEmitter handleSse() {
        SseEmitter emitter = new SseEmitter();
        ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

        executor.scheduleAtFixedRate(() -> {
            try {
                emitter.send("Hello at " + System.currentTimeMillis());
            } catch (IOException e) {
                emitter.completeWithError(e);
            }
        }, 0, 1, TimeUnit.SECONDS);

        emitter.onCompletion(executor::shutdown);

        return emitter;
    }
}
3. 客户端订阅

客户端可以使用 JavaScript 原生的 EventSource 对象来订阅事件。

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>SSE Example</title>
</head>
<body>
    <h1>SSE Example</h1>
    <div id="events"></div>
    <script>
        const eventSource = new EventSource('/sse');
        eventSource.onmessage = function(event) {
            const newElement = document.createElement("div");
            newElement.textContent = event.data;
            document.getElementById("events").appendChild(newElement);
        };
    </script>
</body>
</html>

解释

  1. 创建 SseEmitter 实例 :在服务器端控制器中,通过调用 new SseEmitter() 创建一个 SseEmitter 实例。
  2. 定期发送消息 :使用调度任务定期向客户端发送消息。SseEmittersend 方法用于发送事件。
  3. 处理异常 :在发送消息时处理可能的 IOException,并通过 completeWithError 方法通知客户端连接终止。
  4. 客户端接收消息 :客户端通过 EventSource 对象订阅服务器推送的事件,并通过 onmessage 处理接收到的消息。

注意事项

  1. 连接管理 :需要合理管理 SseEmitter 的生命周期,确保在连接完成、错误或超时时正确关闭。
  2. 浏览器支持:SSE 是大多数现代浏览器支持的技术,但在一些老旧浏览器中可能不受支持。
  3. 数据格式:SSE 传输的数据格式是文本,通常使用 JSON 格式传输结构化数据。

SseEmitter 提供了一种简洁高效的方法来实现服务器到客户端的实时数据推送,适合于许多实时应用场景。

相关推荐
南浔Pyer1 小时前
AI驱动的Java开发框架:Spring AI Alibaba实战部署教程
java·人工智能·spring boot·spring·maven·idea
神的孩子都在歌唱3 小时前
行为设计模式 -模板方法模式- JAVA
java·设计模式·模板方法模式
Satan7124 小时前
【Java】虚拟机(JVM)内存模型全解析
java·开发语言·jvm
远望樱花兔6 小时前
【d54_2】【Java】【力扣】142.环形链表
java·leetcode·链表
IT学长编程6 小时前
计算机毕业设计 助农产品采购平台的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·计算机毕业设计选题·助农产品采购平台
2401_857297916 小时前
2025校招内推-招联金融
java·前端·算法·金融·求职招聘
编啊编程啊程6 小时前
一文上手Kafka【下】
java·分布式·中间件·kafka
誓则盟约6 小时前
基于Spring框架的分层解耦详解
java·后端·spring
旺旺碎冰冰、7 小时前
Java之多态
java·开发语言
今天不coding7 小时前
今年Java回暖了吗
java·开发语言