在Spring Boot中使用SeeEmitter类实现EventStream流式编程将实时事件推送至客户端

在这里插入图片描述

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

在Spring Boot中使用SeeEmitter类实现EventStream流式编程

  • 引言
  • 什么是 Server-Sent Events(SSE)?
  • 为什么选择 SeeEmitter?
  • 开始实战
    • ❶ 添加依赖
    • ❷ 创建事件服务类
    • ❸ 创建事件控制器
    • ❹ 客户端实现
  • 运行应用
  • 总结

引言

随着现代 Web 开发对实时数据处理需求的增加,流式编程(Stream Programming)和事件驱动架构(Event-Driven Architecture)越来越受到关注。在这种架构下,服务器端持续推送实时数据到客户端是非常常见的需求。实现这一目标的技术之一是 Server-Sent Events(SSE),它是一种基于 HTTP 协议的单向通信机制,可以让服务器推送事件到浏览器或客户端。

什么是 Server-Sent Events(SSE)?

Server-Sent Events(SSE)是浏览器与服务器之间的一种通信机制,允许服务器向客户端发送事件流。与 WebSocket 不同,SSE 是单向通信,适用于需要实时更新数据的场景,如通知、新闻推送、实时数据更新等。

SSE 的工作方式是:客户端发起一个 HTTP 请求,服务器返回一个持续开放的响应流。通过这个流,服务器可以不断向客户端发送事件数据,如下图:
在这里插入图片描述

为什么选择 SeeEmitter?

SeeEmitterSpring Framework 5 引入的一个功能类,用于在响应中实现流式数据推送。与传统的 HTTP 响应不同,SeeEmitter 提供了一种方式,能够将数据持续推送到客户端。这个机制非常适合用于构建事件驱动架构,尤其是在实时消息推送、实时数据更新等场景下。

SeeEmitter 基于 Spring WebFlux支持非阻塞的事件流处理,能够处理高并发场景下的数据推送。

开始实战

这里博主将通过一个简单的示例,展示如何在 Spring Boot 中使用 SeeEmitter 实现 EventStream 流式编程,带大家进行一个简单入门

❶ 添加依赖

pom.xml 中添加 WebFlux 相关依赖,因为 SeeEmitter 是 WebFlux 的一部分。

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

❷ 创建事件服务类

在这个类中,我们将生成一个模拟的实时数据源,并通过 SeeEmitter 将数据推送给客户端。

import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;import java.util.concurrent.TimeUnit;@Service
public class EventService {/*** 模拟一个事件流*/public SseEmitter generateEventStream() {SseEmitter emitter = new SseEmitter();// 在独立线程中模拟推送事件new Thread(() -> {try {for (int i = 1; i <= 10; i++) {// 每隔 2 秒发送一次事件数据TimeUnit.SECONDS.sleep(2);emitter.send(SseEmitter.event().name("message").data("Event #" + i));}emitter.complete();  // 完成事件推送} catch (Exception e) {emitter.completeWithError(e);  // 发生错误时,通知客户端}}).start();return emitter;}
}

❸ 创建事件控制器

控制器类负责处理客户端的请求,并返回 SseEmitter 事件流。每当客户端通过 HTTP 请求访问事件流时,控制器会生成一个新的事件流并持续推送数据。

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 EventController {private final EventService eventService;public EventController(EventService eventService) {this.eventService = eventService;}/*** 通过 GET 请求返回 SSE 事件流*/@GetMapping("/event-stream")public SseEmitter streamEvents() {return eventService.generateEventStream();}
}

❹ 客户端实现

为了查看事件流的效果,你可以使用浏览器直接访问 Spring Boot 启动后的请求地址,如:http://localhost:8080/event-stream,或使用 JavaScript 实现客户端订阅事件流。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Event Stream Example</title><script>const eventSource = new EventSource('/event-stream');eventSource.onmessage = function (event) {const message = event.data;const newMessage = document.createElement('div');newMessage.textContent = message;document.getElementById('messages').appendChild(newMessage);};eventSource.onerror = function (error) {console.error("EventSource failed:", error);};</script>
</head>
<body><h1>Real-time Event Stream</h1><div id="messages"></div>
</body>
</html>

运行应用

1、启动 Spring Boot 应用
2、打开浏览器,访问 http://localhost:8080/event-stream,你将看到不断推送的事件数据
3、每隔 2 秒,浏览器会显示一个新的事件,如 Event #1, Event #2 等

总结

相信大家通过博主的简单示例,你已经学会了如何在 Spring Boot 中使用 SeeEmitter 实现流式编程(EventStream)。这一机制非常适合实时数据推送、事件驱动架构以及微服务中的异步消息处理。通过 WebFlux 的非阻塞能力,SeeEmitter 能够处理高并发的流式数据传输,是构建高效、可扩展应用的有力工具。

流式编程不仅仅是响应用户请求的方式,它也能为你提供更强的可扩展性和实时性,特别是在构建实时更新、推送通知等功能时,SeeEmitter 是一个非常理想的解决方案。如果本文对您有所帮助,希望 一键三连 给博主一点点鼓励,如果您有任何疑问或建议,请随时留言讨论!
在这里插入图片描述

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

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

相关文章

基于本地事务表+MQ实现分布式事务

基于本地事务表MQ实现分布式事务 引言1、原理2、本地消息表优缺点3、本地启动rocketmq4、代码实现及验证4.1、核心代码4.2、代码执行流程4.3、项目结构4.4、项目源码 引言 本地消息表的方案最初由ebay的工程师提出&#xff0c;核心思想是将分布式事务拆分成本地事务进行处理。…

Chrome插件:图片缩放为头像(128*128)

前置条件&#xff1a; 安装有chrome谷歌浏览器的电脑 使用步骤&#xff1a; 1.打开chrome扩展插件 2.点击管理扩展程序 3.加载已解压的扩展程序 4.选择对应文件夹 5.成功后会出现一个扩展小程序 6.点击对应小程序 7.使用小程序 8.拖拽成功后会自动保存到下载 代码&#xf…

idea maven本地有jar包,但还要从远程下载

idea 中&#xff0c;java 工程执行 maven reimport&#xff0c;报jar报无法下载。 我奇了个怪&#xff0c;我明明在本地仓库有啊&#xff0c;你非得从远程下载&#xff1f; 我从供应商那里拿来的&#xff0c;远程当然没有了。 这太奇葩了吧&#xff0c;折腾好久不行。 后来…

HTML<label>标签

例子 三个带标签的单选按钮&#xff1a; <form action"/action_page.php"> <input type"radio" id"html" name"fav_language" value"HTML"> <label for"html">HTML</label><br&…

【数据结构】_不带头非循环单向链表

目录 1. 链表的概念及结构 2. 链表的分类 3. 单链表的实现 3.1 SList.h头文件 3.2 SList.c源文件 3.3 Test_SList.c测试文件 关于线性表&#xff0c;已介绍顺序表&#xff0c;详见下文&#xff1a; 【数据结构】_顺序表-CSDN博客 本文介绍链表&#xff1b; 基于顺序表…

算法刷题笔记——图论篇

这里写目录标题 理论基础图的基本概念图的种类度 连通性连通图强连通图连通分量强连通分量 图的构造邻接矩阵邻接表 图的遍历方式 深度优先搜索理论基础dfs 与 bfs 区别dfs 搜索过程深搜三部曲所有可达路径广度优先搜索理论基础广搜的使用场景广搜的过程 岛屿数量孤岛的总面积沉…

“AI视觉贴装系统:智能贴装,精准无忧

嘿&#xff0c;朋友们&#xff01;今天我要跟你们聊聊一个特别厉害的技术——AI视觉贴装系统。这可不是普通的贴装设备&#xff0c;它可是融合了人工智能、计算机视觉和自动化控制等前沿科技的“智能贴装大师”。有了它&#xff0c;那些繁琐、复杂的贴装工作变得轻松又精准。来…

vim如何设置显示空白符

:set list 显示空白符 示例&#xff1a; :set nolist 不显示空白符 示例&#xff1a; &#xff08;vim如何使设置显示空白符永久生效&#xff1a;vim如何使相关设置永久生效-CSDN博客&#xff09;

Flutter android debug 编译报错问题。插件编译报错

下面相关内容 都以 Mac 电脑为例子。 一、问题 起因&#xff1a;&#xff08;更新 Android studio 2024.2.2.13、 Flutter SDK 3.27.2&#xff09; 最近 2025年 1 月 左右&#xff0c;我更新了 Android studio 和 Flutter SDK 再运行就会出现下面的问题。当然 下面的提示只是其…

AI导航工具我开源了利用node爬取了几百条数据

序言 别因今天的懒惰&#xff0c;让明天的您后悔。输出文章的本意并不是为了得到赞美&#xff0c;而是为了让自己能够学会总结思考&#xff1b;当然&#xff0c;如果有幸能够给到你一点点灵感或者思考&#xff0c;那么我这篇文章的意义将无限放大。 背景 随着AI的发展市面上…

Android Studio打包APK

1.导出APK安装包 如果是首次打包&#xff0c;Create new 单击蓝色对话框右边文件夹&#x1f4c2;图标 &#xff0c;选择密钥保存路径&#xff0c;然后在下方File name对话框中填写您想要名称&#xff0c;再点击OK回到密钥创建对话框。 在此对话框中填写密码&#xff08;Passwo…

ssh密钥登录GitHub时一直提示“Error: Permission denied (publickey)”

起因 环境&#xff1a;Windows10 背景&#xff1a;之前就是按照官方说明创建个rsa密钥&#xff0c;在git后台添加上&#xff0c;就行了&#xff0c;近期怎么添加怎么失败&#xff0c;总是“Error: Permission denied (publickey)”的提示&#xff01; 尝试 各种尝试&#xf…

【玩转全栈】----Django连接MySQL

阅前先赞&#xff0c;养好习惯&#xff01; 目录 1、ORM框架介绍 选择建议 2、安装mysqlclient 3、创建数据库 4、修改settings&#xff0c;连接数据库 5、对数据库进行操作 创建表 删除表 添加数据 删除数据 修改&#xff08;更新&#xff09;数据&#xff1a; 获取数据 1、OR…

软件质量与测试报告5-压力测试 JMeter 与 Badboy

A&#xff0e;百度搜索引擎压力测试 通过在Badboy下执行如下的测试场景来生成压力测试的脚本&#xff1a; a) 在Badboy的地址栏里面输入www.baidu.com&#xff0c;回车&#xff1b; b) 在右下区域打开的百度的主页上输入搜索关键字JMeter&#xff0c;回车&#xff1b; c) 在…

vim如何显示行号

:set nu 显示行号 :set nonu 不显示行号 &#xff08;vim如何使设置显示行号永久生效&#xff1a;vim如何使相关设置永久生效-CSDN博客&#xff09;

Python Typing: 实战应用指南

文章目录 1. 什么是 Python Typing&#xff1f;2. 实战案例&#xff1a;构建一个用户管理系统2.1 项目描述2.2 代码实现 3. 类型检查工具&#xff1a;MyPy4. 常见的 typing 用法5. 总结 在 Python 中&#xff0c;静态类型检查越来越受到开发者的重视。typing 模块提供了一种方式…

Linux的基本指令(上)

1.ls指令 语法&#xff1a;ls [选项] [目录或文件] 功能&#xff1a;对于⽬录&#xff0c;该命令列出该⽬录下的所有⼦⽬录与⽂件。对于⽂件&#xff0c;将列出⽂件名以及其他信息。 常用选项&#xff1a; -a 列出⽬录下的所有⽂件&#xff0c;包括以 . 开头的隐含⽂件。 -d 将…

【数据分享】1929-2024年全球站点的逐日平均能见度(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff01;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2024年全球气象站点…

算法每日双题精讲 —— 二分查找(山脉数组的峰顶索引,寻找峰值)

&#x1f31f;快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 &#x1f31f; 别再犹豫了&#xff01;快来订阅我们的算法每日双题精讲专栏&#xff0c;一起踏上算法学习的精彩之旅吧&#x1f4aa; 在算法的…

macOS如何进入 Application Support 目录(cd: string not in pwd: Application)

错误信息 cd: string not in pwd: Application 表示在当前目录下找不到名为 Application Support 的目录。可能的原因如下&#xff1a; 拼写错误或路径错误&#xff1a;确保你输入的目录名称正确。目录名称是区分大小写的&#xff0c;因此请确保使用正确的大小写。正确的目录名…