轻松实现服务器事件主动推送到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 提供了一种简洁高效的方法来实现服务器到客户端的实时数据推送,适合于许多实时应用场景。

相关推荐
chusheng184016 分钟前
Java基于SpringBoot+Vue的藏区特产销售平台
java·vue.js·spring boot·藏区特产销售平台·特产销售平台
Java学长-kirito18 分钟前
springboot/ssm网购平台管理系统Java在线购物商城管理平台web电商源码
java·前端·spring boot
飞滕人生TYF1 小时前
java 排序 详解
java·算法·排序算法·方法
Java小王子呀1 小时前
java使用itext生成pdf
java·pdf
JWASX1 小时前
定时/延时任务-Timer用法
java·定时器·timer
大风吹PP凉2 小时前
45系统调用与内核API
java·linux·服务器
as_jopo2 小时前
-Dspring.profiles.active=dev与--spring.profiles.active=dev的区别
java·后端·spring
hummhumm2 小时前
第 32 章 - Go语言 部署与运维
java·运维·开发语言·后端·python·sql·golang
QQ_1154320312 小时前
基于Java+SpringBoot+Mysql在线简单拍卖竞价拍卖竞拍系统功能设计与实现四
java·spring boot·mysql·毕业设计·毕业源码·竞拍系统·竞拍平台
fa_lsyk2 小时前
Spring:AOP面向切面案例讲解AOP核心概念
java·后端·spring