使用 Spring Boot 实现服务器发送事件(SSE)

服务器发送事件(Server-Sent Events, SSE)是一种允许服务器向客户端推送实时更新的技术。在这篇文章中,我们将教你如何在 Spring Boot 应用中实现 SSE。

流程概述

以下是使用 Spring Boot 实现 SSE 的整体步骤:

步骤 说明
1. 创建 Spring Boot 项目 使用 Spring Initializr 创建项目
2. 添加依赖 pom.xml 中添加必要的依赖
3. 创建 SSE 控制器 编写一个 REST 控制器发送 SSE 数据
4. 监听事件 在前端创建一个页面用 JavaScript 监听事件
5. 测试 SSE 启动应用并测试服务器推送数据

每一步的详细实现

1. 创建 Spring Boot 项目

通过 [Spring Initializr]( 创建一个新的 Spring Boot 项目,选择需要的技术栈(例如,Spring Web)。

2. 添加依赖

pom.xml 文件中,确保包含如下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

3. 创建 SSE 控制器

现在我们需要创建一个控制器来推送数据。创建一个名为 SseController 的 Java 类,并添加以下代码:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import java.io.IOException;
import java.util.concurrent.Flow;
import java.util.concurrent.SubmissionPublisher;

@RestController
public class SseController {

    // 创建一个 SubmissionPublisher 实例,用于发布事件
    private final SubmissionPublisher<String> publisher = new SubmissionPublisher<>();

    // 推送事件的端点
    @GetMapping(value = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public ResponseEntity<Void> streamSse() {
        // 定义一个线程来发布事件
        new Thread(() -> {
            try {
                while (true) {
                    // 在此处生成要发送的数据
                    String data = "当前时间: " + System.currentTimeMillis();
                    // 发布数据
                    publisher.submit(data);
                    // 控制发送频率
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        // 返回 204 No Content
        return ResponseEntity.noContent().build();
    }
}

代码解释

  • 创建了一个 SubmissionPublisher 实例用于发布事件。
  • 定义了一个 GET 请求 /sse 的端点,返回 MediaType.TEXT_EVENT_STREAM_VALUE,表示以 SSE 形式响应。
  • 在新线程中循环生成数据,并每秒发布一次。

4. 监听事件

前端页面需要使用 JavaScript 来监听 SSE。可以在 src/main/resources/static 目录下创建一个 index.html 文件,内容如下:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SSE Example</title>
</head>
<body>
    服务器推送事件
    <div id="result"></div>

    <script>
        // 创建 EventSource 对象
        const eventSource = new EventSource('/sse');

        // 监听消息事件
        eventSource.onmessage = function(event) {
            // 将数据添加到页面中
            document.getElementById('result').innerHTML += event.data + '<br>';
        };
    </script>
</body>
</html>

5. 测试 SSE

启动你的 Spring Boot 应用程序,然后访问 http://localhost:8080/。你应该能看到页面上显示的当前时间,每秒更新一次。

ER 图

下面是系统的简化 ER 图,表达了SSE的结构:

erDiagram
    USER {
        string id
        string name
    }
    EVENT {
        string id
        string data
    }
    USER ||--o{ EVENT : generates

旅行图

以下是与发送事件有关的旅行图:

journey
    title 与 SSE 的交互
    section 启动应用
      启动 Spring Boot 应用: 5: Bob
    section 客户端请求
      客户端访问 /sse: 4: Alice
    section 服务器推送事件
      服务器每秒发送数据: 5: Bob
      客户端接收并展示数据: 4: Alice

结尾

通过以上步骤,你应该能够成功地使用 Spring Boot 实现服务器发送事件(SSE)。这种技术特别适合需要实时更新的应用场景,如聊天应用、实时数据监控等。掌握 SSE 会使你在前端与后端开发中大大提高效率和互动性。如有任何问题,请随时询问!