Springboot 实现Server-Sent Events

Spring Boot 中,返回 text/event-stream 类型的响应通常用于实现 Server-Sent Events (SSE),这种方式允许服务器推送实时更新到浏览器。客户端通过 EventSource API 监听并接收这些事件。Spring Boot 可以通过使用 @RestControllerSseEmitter 来实现这一功能。

步骤 1:创建 SSE Controller 返回 text/event-stream

我们可以通过 @GetMapping 来创建一个 API,返回 text/event-stream 类型的数据。这个数据会是一个持续的流,浏览器会实时地接收它。

示例:通过 Spring Boot 返回 text/event-stream 类型的响应
  1. 控制器:在 Spring Boot 中定义一个返回 text/event-stream 类型的 API 接口。
  2. 使用 SseEmitterSseEmitter 是 Spring 提供的一个类,用于处理 Server-Sent Events 流。我们可以利用它来异步地向客户端推送数据。

示例 1:简单的 SSE 实现

在这个示例中,我们将创建一个简单的 Spring Boot 控制器,该控制器将返回一个实时的事件流(SSE)。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;@RestController
public class SseController {/*** 这个接口会返回一个持续的事件流,浏览器会通过 EventSource 接收*/@GetMapping("/sse")public SseEmitter handleSse() {SseEmitter emitter = new SseEmitter();// 启动一个新的线程模拟定期推送事件new Thread(() -> {try {for (int i = 0; i < 10; i++) {// 向客户端发送数据emitter.send("data: Event " + i + "\n\n");Thread.sleep(1000); // 每秒发送一次}emitter.complete(); // 发送完毕后,标记事件流完成} catch (Exception e) {emitter.completeWithError(e); // 如果出现异常,标记事件流出错}}).start();return emitter; // 返回 SseEmitter 实例,它会处理异步流式数据}
}

说明:

  1. SseEmitter 用于处理 SSE 连接。我们将数据通过 emitter.send() 发送到客户端。
  2. 事件通过 data: <message> 格式发送给客户端,注意每条消息以两个换行符结束(\n\n)。
  3. Thread.sleep(1000) 用于模拟每秒发送一个事件。如果你需要定期发送事件,可以通过类似的机制来实现。
  4. 最后,通过 emitter.complete() 标记事件流结束。如果发生错误,则使用 emitter.completeWithError()

步骤 2:前端接收 SSE 事件

在前端,使用 JavaScript 的 EventSource API 接收服务器推送的事件。这个 API 会保持与服务器的连接,一旦有新的事件,浏览器会自动处理。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Server-Sent Events Example</title>
</head>
<body><h1>Server-Sent Events Example</h1>
<div id="messages"></div><script>// 创建一个 EventSource 对象,连接到 /sse 接口const eventSource = new EventSource("/sse");// 每当接收到数据时,处理该事件eventSource.onmessage = function(event) {const messagesDiv = document.getElementById('messages');const message = document.createElement('p');message.textContent = event.data;messagesDiv.appendChild(message);};// 错误处理eventSource.onerror = function(error) {console.error("EventSource failed:", error);};
</script></body>
</html>

步骤 3:配置 Spring Boot 启用异步支持

SSE 通常需要异步处理,因此在 Spring Boot 中启用异步支持是非常重要的。可以通过 @EnableAsync 来启用异步支持。

启用异步支持
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;@Configuration
@EnableAsync
public class AsyncConfig {
}

步骤 4:定时推送数据(可选)

如果你希望定期推送事件(例如,每隔一定时间推送一个消息),可以使用 Spring 的 @Scheduled 注解来安排定时任务。

示例:定时发送事件
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;@Controller
public class ScheduledSseController {private final SseEmitter emitter = new SseEmitter();@Scheduled(fixedRate = 5000)  // 每5秒发送一个事件public void sendScheduledEvent() {try {emitter.send("data: Scheduled Event at " + System.currentTimeMillis() + "\n\n");} catch (IOException e) {emitter.completeWithError(e);}}
}

在上面的示例中,@Scheduled(fixedRate = 5000) 会定期每 5 秒发送一次事件。

步骤 5:处理多客户端连接

如果你需要管理多个客户端连接,可以将 SseEmitter 实例存储在一个列表中,并为每个连接发送事件。每当有新事件时,你可以通过遍历这些连接,发送事件到所有连接的客户端。

import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import org.springframework.web.bind.annotation.GetMapping;import java.io.IOException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;@Controller
public class MultiClientSseController {private final List<SseEmitter> emitters = new CopyOnWriteArrayList<>();@GetMapping("/sse")public SseEmitter handleSse() {SseEmitter emitter = new SseEmitter();emitters.add(emitter);// 在新线程中发送数据new Thread(() -> {try {for (int i = 0; i < 10; i++) {for (SseEmitter e : emitters) {e.send("data: Event " + i + "\n\n");}Thread.sleep(1000); // 每秒发送一次}} catch (Exception e) {emitters.forEach(SseEmitter::completeWithError);}}).start();return emitter;}
}

总结

  1. 返回 text/event-stream:在 Spring Boot 控制器中使用 SseEmitter 或直接通过 @GetMapping 返回流式数据。
  2. 前端接收事件:使用浏览器的 EventSource API 来接收事件流。
  3. 定时事件:可以使用 @Scheduled 来定期推送事件,或者通过后台线程推送动态数据。
  4. 多客户端支持:可以管理多个 SseEmitter 实例,为每个客户端推送事件。

这种方式非常适合实时数据推送,例如股票行情更新、社交媒体通知、实时消息等应用场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/479453.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用UE5.5的Animator Kit变形器

UE5.5版本更新了AnimatorKit内置插件&#xff0c;其中包含了一些内置变形器&#xff0c;可以辅助我们的动画制作。 操作步骤 首先打开UE5.5&#xff0c;新建第三人称模板场景以便测试&#xff0c;并开启AnimatorKit组件。 新建Sequence&#xff0c;放入测试角色 点击角色右…

Uniapp 安装安卓、IOS模拟器并调试

一、安装Android模拟器并调试 1. 下载并安装 Android Studio 首先下载 Mac 环境下的 Android Studio 的安装包&#xff0c;为dmg 格式。 下载完将Android Studio 向右拖拽到Applications中&#xff0c;接下来等待安装完成就OK啦&#xff01; 打开过程界面如下图所示&#xf…

shell(5)字符串运算符和逻辑运算符

声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&#…

【金蝶双线指标】以看资金进出操作为主,兼顾波段跟踪和短线低吸

如上图&#xff0c;个股副图指标&#xff0c;大佬资金监控短线低吸攻击线操盘线趋势红蝴蝶&#xff0c;五大功能于一体。下面慢慢给大家仔细分享。 大佬资金监控指标&#xff0c;红绿进出&#xff0c;绿色缩小到极致&#xff0c;接近零轴&#xff0c;红绿柱分界线&#xff0c;为…

多输入多输出 | Matlab实现TCN-GRU时间卷积神经网络结合门控循环单元多输入多输出预测

多输入多输出 | Matlab实现TCN-GRU时间卷积神经网络结合门控循环单元多输入多输出预测 目录 多输入多输出 | Matlab实现TCN-GRU时间卷积神经网络结合门控循环单元多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 多输入多输出 | Matlab实现TCN-GRU时间卷积…

HCIA笔记4--VLAN划分

1. vlan是什么 vlan: virtual lan; 虚拟局域网的简称。 主要目的是隔离广播域。 2. vlan报文格式 在普通的以太网数据帧开关的12字节后添加4字节的vlan tag。而来区分vlan的是其中的vid部分12个比特位&#xff0c;范围自然就是0~2^12-1(0~4095); 0 4095保留使用。实际使用的是…

蓝牙定位的MATLAB仿真程序|基于信号强度的定位,平面、四个蓝牙基站(附源代码)

这段代码通过RSSI信号强度实现了蓝牙定位&#xff0c;展示了如何使用锚点位置和测量的信号强度来估计未知点的位置。它涵盖了信号衰减模型、距离计算和最小二乘法估计等基本概念。通过图形化输出&#xff0c;用户可以直观地看到真实位置与估计位置的关系。 文章目录 蓝牙定位原…

基于Springboot企业级工位管理系统【附源码】

基于Springboot企业级工位管理系统 效果如下&#xff1a; 系统登录页面 员工主页面 部门信息页面 员工管理页面 部门信息管理页面 工位信息管理页面 工位分配管理页面 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所。…

Spring Boot教程之十: 使用 Spring Boot 实现从数据库动态下拉列表

使用 Spring Boot 实现从数据库动态下拉列表 动态下拉列表&#xff08;或依赖下拉列表&#xff09;的概念令人兴奋&#xff0c;但编写起来却颇具挑战性。动态下拉列表意味着一个下拉列表中的值依赖于前一个下拉列表中选择的值。一个简单的例子是三个下拉框&#xff0c;分别显示…

SpringBoot源码-spring boot启动入口ruan方法主线分析(一)

一、SpringBoot启动的入口 1.当我们启动一个SpringBoot项目的时候&#xff0c;入口程序就是main方法&#xff0c;而在main方法中就执行了一个run方法。 SpringBootApplication public class StartApp {public static void main(String[] args) {// testSpringApplication.ru…

AI 助力开发新篇章:云开发 Copilot 深度体验与技术解析

本文 一、引言&#xff1a;技术浪潮中的个人视角1.1 AI 和低代码的崛起1.2 为什么选择云开发 Copilot&#xff1f; 二、云开发 Copilot 的核心功能解析2.1 自然语言驱动的低代码开发2.1.1 自然语言输入示例2.1.2 代码生成的模块化支持 2.2 实时预览与调整2.2.1 实时预览窗口功能…

vscode的markdown扩展问题

使用vscode编辑markdown文本时&#xff0c;我是用的是Office Viewer(Markdown Editor)这个插件 今天突然发现不能用了&#xff0c;点击切换编辑视图按钮时会弹出报错信息&#xff1a; command office.markdown.switch not found 在网上找了很久发现没有有关这个插件的文章………

从零开始学 Maven:简化 Java 项目的构建与管理

一、关于Maven 1.1 简介 Maven 是一个由 Apache 软件基金会开发的项目管理和构建自动化工具。它主要用在 Java 项目中&#xff0c;但也可以用于其他类型的项目。Maven 的设计目标是提供一种更加简单、一致的方法来构建和管理项目&#xff0c;它通过使用一个标准的目录布局和一…

去哪儿大数据面试题及参考答案

Hadoop 工作原理是什么&#xff1f; Hadoop 是一个开源的分布式计算框架&#xff0c;主要由 HDFS&#xff08;Hadoop 分布式文件系统&#xff09;和 MapReduce 计算模型两部分组成 。 HDFS 工作原理 HDFS 采用主从架构&#xff0c;有一个 NameNode 和多个 DataNode。NameNode 负…

守护进程

目录 守护进程 前台进程 后台进程 session&#xff08;进程会话&#xff09; 前台任务和后台任务比较好 本质 绘画和终端都关掉了&#xff0c;那些任务仍然在 bash也退了&#xff0c;然后就托孤了 ​编辑 守护进程化---不想受到任何用户登陆和注销的影响​编辑 如何…

element ui select绑定的值是对象的属性时,显示异常.

需要声明 value-key"value". el-select v-model"value" clearable placeholder"Select" value-key"value" style"width: 240px"><!-- <el-option v-for"item in options" :key"item.value" :…

SAAS美容美发系统架构解析

随着技术的不断发展&#xff0c;SAAS&#xff08;Software as a Service&#xff0c;软件即服务&#xff09;模式在各个行业的应用逐渐深化&#xff0c;美容美发行业也不例外。传统的美容美发店面通常依赖纸质记录、手动操作和复杂的管理流程&#xff0c;而随着SAAS平台的出现&…

[代码随想录Day24打卡] 93.复原IP地址 78.子集 90.子集II

93.复原IP地址 一个合法的IP地址是什么样的&#xff1a; 有3个’.分割得到4个数&#xff0c;每个数第一个数不能是0&#xff0c;不能含有非法字符&#xff0c;不能大于255。 这个是否属于合法IP相当于一个分割问题&#xff0c;把一串字符串分割成4部分&#xff0c;分别判断每…

Java学习笔记--继承方法的重写介绍,重写方法的注意事项,方法重写的使用场景,super和this

目录 一&#xff0c;方法的重写 二&#xff0c;重写方法的注意事项 三&#xff0c;方法重写的使用场景 四&#xff0c;super和this 1.继承中构造方法的特点 2.super和this的具体使用 super的具体使用 this的具体使用 一&#xff0c;方法的重写 1.概述:子类中有一个和父类…

gRPC 双向流(Bidirectional Streaming RPC)的使用方法

gRPC 是一个支持多种语言的高性能 RPC 框架&#xff0c;拥有丰富的 API 来简化服务端和客户端的开发过程。gRPC 支持四种 RPC 类型&#xff1a;Unary RPC、Server Streaming RPC、Client Streaming RPC 和 Bidirectional Streaming RPC。下面是双向流 API 的使用方法。 双向流…