当前位置: 首页 > news >正文

Spring Boot 应用中实现基本的 SSE 功能

SSE 技术简介

SSE(Server-Sent Events)是一种允许服务器主动向客户端推送数据的技术。它基于 HTTP 长连接,使用简单,特别适合实时数据更新场景,如股票行情、新闻推送等。与 WebSocket 相比,SSE 更轻量级,且只支持服务器到客户端的单向通信。

Spring Boot 集成 SSE

下面我将介绍如何在 Spring Boot 中实现 SSE 功能:

1. 添加依赖

首先在 pom.xml 中添加 Spring Web 依赖:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>
2. 创建 SSE 控制器

以下是一个简单的 SSE 控制器示例,它可以定时向客户端推送消息:

package com.example.sse.demo.controller;import org.springframework.http.MediaType;
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 {// 创建一个单线程的调度器private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);@GetMapping(path = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public SseEmitter streamSseMvc() {SseEmitter emitter = new SseEmitter(60_000L); // 设置超时时间为60秒// 启动定时任务,每秒发送一次消息scheduler.scheduleAtFixedRate(() -> {try {// 发送数据emitter.send(SseEmitter.event().id(String.valueOf(System.currentTimeMillis())).name("message").data("Hello, SSE! Time: " + System.currentTimeMillis()));} catch (IOException e) {// 发生异常时,完成发射器emitter.completeWithError(e);}}, 0, 1, TimeUnit.SECONDS);// 设置完成回调emitter.onCompletion(() -> System.out.println("SSE connection completed"));// 设置超时回调emitter.onTimeout(() -> {System.out.println("SSE connection timed out");emitter.complete();});// 设置错误回调emitter.onError((ex) -> {System.out.println("SSE connection error: " + ex.getMessage());emitter.completeWithError(ex);});return emitter;}
}
3. 创建客户端页面

创建一个简单的 HTML 页面来接收服务器推送的消息:

<!DOCTYPE html>
<html>
<head><title>SSE Demo</title><style>body {font-family: Arial, sans-serif;margin: 20px;}#messages {border: 1px solid #ccc;padding: 10px;margin-top: 10px;height: 200px;overflow-y: auto;}</style>
</head>
<body><h1>SSE Demo</h1><button onclick="startSse()">Start SSE</button><button onclick="stopSse()">Stop SSE</button><div id="messages"></div><script>let eventSource;function startSse() {// 创建 EventSource 实例连接到服务器eventSource = new EventSource('/sse');// 监听 message 事件eventSource.onmessage = function(event) {const messagesDiv = document.getElementById('messages');const newMessage = document.createElement('div');newMessage.textContent = `[${new Date().toLocaleTimeString()}] ${event.data}`;messagesDiv.appendChild(newMessage);};// 监听错误事件eventSource.onerror = function(error) {console.error('EventSource failed:', error);const messagesDiv = document.getElementById('messages');const errorMessage = document.createElement('div');errorMessage.textContent = `Error: ${error}`;errorMessage.style.color = 'red';messagesDiv.appendChild(errorMessage);// 关闭连接eventSource.close();};}function stopSse() {if (eventSource) {eventSource.close();const messagesDiv = document.getElementById('messages');const statusMessage = document.createElement('div');statusMessage.textContent = 'Connection closed';statusMessage.style.color = 'blue';messagesDiv.appendChild(statusMessage);}}</script>
</body>
</html>

运行和测试

  1. 启动 Spring Boot 应用
  2. 访问客户端页面(例如:http://localhost:8080/index.html
  3. 点击 “Start SSE” 按钮开始接收服务器推送的消息
  4. 点击 “Stop SSE” 按钮停止接收消息

关键技术点说明

  1. 服务器端

    • 使用 SseEmitter 处理 SSE 连接
    • 设置适当的超时时间
    • 实现错误处理和连接关闭逻辑
    • 使用 MediaType.TEXT_EVENT_STREAM_VALUE 指定响应类型
  2. 客户端

    • 使用 EventSource 对象连接到 SSE 服务器
    • 监听 message 事件接收服务器推送的数据
    • 监听 error 事件处理连接错误
    • 使用 close() 方法关闭连接

注意事项

  1. 生产环境中应考虑使用连接池和更健壮的错误处理机制
  2. 长时间运行的 SSE 连接可能需要处理网络中断和重连问题
  3. 考虑添加身份验证和授权机制保护 SSE 端点
  4. 对于大量并发连接,应评估服务器性能和资源消耗

通过以上步骤,你可以在 Spring Boot 应用中实现基本的 SSE 功能,实现服务器向客户端的实时数据推送。

http://www.xdnf.cn/news/422659.html

相关文章:

  • 鸿蒙 核心与非核心装饰器
  • [Java实战]Spring Boot 3 整合 Ehcache 3(十九)
  • Python慕课学习记录报告
  • c# UTC 时间赋值注意事项
  • Linux:进程控制2
  • 医疗实时操作系统方案:手术机器人的微秒级运动控制
  • 单反和无反(私人笔记)
  • 高并发系统设计需要考虑哪些问题
  • 极限学习机进行电厂相关数据预测
  • 目标检测任务常用脚本1——将YOLO格式的数据集转换成VOC格式的数据集
  • 滑动窗口——水果成篮
  • 正则表达式常用验证(一)
  • vim,gcc/g++,makefile,cmake
  • 如何用URDF文件构建机械手模型并与MoveIt集成
  • 获取accesstoken时,提示证书解析有问题,导致无法正常获取token
  • do while
  • 从代码学习深度学习 - 全卷积神经网络 PyTorch版
  • 【网络编程】七、详解HTTP 搭建HTTP服务器
  • MySQL 5.7在CentOS 7.9系统下的安装(上)——以rpm包的形式下载mysql
  • 音频特征工具Librosa包的使用
  • Windows Java gRPC 示例
  • windowsC++操作ADB
  • archlinux中挂载macOS的硬盘
  • keepalived+lvs
  • S32DS删除历史安装的license code(Software Activation Code)
  • 什么是序列化与反序列化
  • CodeBuddy终极测评:中国版Cursor的开发革命(含安装指南+HTML游戏实战)
  • 计算机网络网络层(下)
  • 奇妙小博客
  • 虚拟仿真技术在康养休闲旅游服务实训室中的核心应用