SSE 实践:用 Vue 和 Spring Boot 实现实时数据传输

前言

大家好,我是雪荷。最近我在灵犀 BI 项目中引入了 SSE 技术,以保证图表的实时渲染,当图表渲染完毕服务端推送消息至浏览器端触发重新渲染。

什么是 SSE?

SSE 全称为 Server-Send Events 意思是服务端推送事件。

SSE 相比于 Websocket 它基于 Http 实现无需实现其他协议、更加轻量级、支持自动重连,但只能服务端推送消息给客户端,客户端不能推送消息给服务端。适用于服务端主动推送数据,客户端只需接收数据的场景。以下为 SSE 与 Websocket 的对比:

SSEWebsocket
通信单向通信(服务端到客户端)双向通信
协议HttpWebsocket
自动重连支持不支持,要客户端自行支持
数据格式文本格式,如果要二进制数据得自行编码默认二进制数据、支持文本格式
浏览器兼容性大部分支持主流浏览器支持较好

Vue + Spring Boot 实现一个 SSE demo

后端实现

由于 SSE 基于 http 协议实现,因此我们无需引入第三方 jar 包。首先通过 idea 创建一个 spring boot 项目,记得勾选 spring web 依赖。

image-20250117095658768

创建一个跨域配置,因为前后端的端口不同,会出现请求跨域。

@Configuration
public class CorsConfig implements WebMvcConfigurer {
​@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOriginPatterns("*").allowedMethods("GET", "POST", "PUT", "DELETE").allowedHeaders("*").allowCredentials(true);}
}
随后创建一个 SSEcontroller,用来创建 SSE 连接和推送消息给客户端。
@RestController
@RequestMapping("/sse")
public class SSEController {
​private static final Map<Integer, SseEmitter> sseEmitters = new ConcurrentHashMap<>();
​@GetMapping("/create")public SseEmitter createSSEConnection() {// 创建SSE连接SseEmitter emitter = new SseEmitter();// 将 sseEmitter 赛道 map 中,方便管理多个 sse 连接,比如可以为每个用户创建一个 sse 连接,以用户 id 为 map 的 keysseEmitters.put(1, emitter);emitter.onCompletion(() -> sseEmitters.remove(1));emitter.onTimeout(() -> sseEmitters.remove(1));return emitter;}
​@PostMapping("/send")public void sendSSEMessage() {// 发送消息SseEmitter sseEmitter = sseEmitters.get(1);if (sseEmitter != null) {for (int i = 0; i < 3; i++) {try {sseEmitter.send(SseEmitter.event().data("hello world") // 发送的数据,是 Object 类型.name("sse-message")); // 定义 SSE 事件的名称,方便前端监听} catch (IOException e) {sseEmitters.remove(1);}}}}
​
}

在上面的代码中,createSSEConnection 用来创建 sse 连接,注意其请求方法为 get,post 是不能创建的,因为前端发的就是 get 请求。我还创建了一个 sseEmitters 的 Map<Integer, SseEmitter> 来管理 sse 连接,在项目中 map 的 key 可以作为客户端标识,可以是用户 id 或者某些业务参数。当创建完毕后将 sseEmiter 塞到 map 中,当 sse 连接超时或者完成就删掉在 map 中对应的 value。

而 sendSSEMessage 方法就是服务端向客户端推送消息的实例代码,这里我们方便我写了一个请求来触发服务端发消息给客户端,实际是根据具体业务来主动推消息给客户端。比如异步生成图表或者插入数据时,当此动作完毕后可以发消息给前端表明操作成功。那如何发送消息就不用我说了,先从 map 取出 sseEmitter,接着添加事件名和要发送的数据就好了。

如果是前端传送参数来创建 sse 连接的话,可以这样操作。

    @GetMapping("/create")public SseEmitter createSSEConnection(@RequestParam Integer id) {// 创建SSE连接SseEmitter emitter = new SseEmitter();sseEmitters.put(id, emitter);emitter.onCompletion(() -> sseEmitters.remove(1));emitter.onTimeout(() -> sseEmitters.remove(1));return emitter;}

前端实现

首先创建一个 vue 项目,引入一些基础依赖,比如 aixos,项目具体结构如下:

image-20250117101231521

myAxios.js:

import axios from 'axios';
​
const myAxios = axios.create({baseURL: 'http://localhost:8080',
})
​
myAxios.defaults.withCredentials = true; //设置为true
​
​
export default myAxios;

然后 SSEDemo.vue 就是主要创建 sse 连接和接受服务端发送消息

SSEDemo.vue:

<template><div><h3>接收到的消息:</h3><ul><li v-for="(message, index) in messages" :key="index">{{ message }}</li></ul></div><button @click="sendMessage">发送消息</button>
</template>
​
<script>
import {onBeforeUnmount, onMounted, ref} from 'vue';
import myAxios from "@/plugins/myAxios.js";
​
export default {setup() {const messages = ref([]); // 存储接收到的消息let eventSource = null; // 用于保存 EventSource 实例
​onMounted(() => {// 创建 EventSource 实例,连接到服务器端的 SSE 端点eventSource = new EventSource('http://localhost:8080/sse/create');
​// 监听特定事件名 'sse-message'eventSource.addEventListener('sse-message', (event) => {console.log('收到消息:', event.data);// 解析消息并保存到 messages 中messages.value.push(event.data);});
​// 监听连接关闭或错误eventSource.onerror = (error) => {console.error('SSE 连接出错:', error);eventSource.close(); // 关闭连接};});
​onBeforeUnmount(() => {// 组件销毁时关闭 SSE 连接if (eventSource) {eventSource.close();}});
​const sendMessage = async () => {await myAxios.post('/sse/send');}
​return {messages,sendMessage};},
};
</script>

new EventSource 新建一个事件源,其会向后端发送请求方法为 get 的 http 请求,利用 eventSource.addEventListener 创建一个事件监听器并带上事件名就可以完成事件的监听和消息发送啦。

最后运行前后端项目,打开前端地址会看到有一个 http 显示待处理。

image-20250117102000639

点击发送消息按钮使后端发送消息给前端,前端接收到就会实时显示。

image-20250117102058899

开源项目

厚米匹配

网址:厚米匹配系统

前端仓库:https://github.com/dnwwdwd/homieMatching-fronted

后端仓库:https://github.com/dnwwdwd/homieMatching

灵犀 BI

网址:鱼智能 BI

前端仓库:https://github.com/dnwwdwd/Lingxi-BI-fronted

后端仓库:https://github.com/dnwwdwd/Lingxi-BI

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

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

相关文章

记录一次 centos 启动失败

文章目录 现场1分析1现场2分析2搜索实际解决过程 现场1 一次断电,导致 之前能正常启动的centos 7.7 起不来了有部分log , 关键信息如下 [1.332724] XFS(sda3): Internal error xfs ... at line xxx of fs/xfs/xfs_trans.c [1.332724] XFS(sda3): Corruption of in-memory data…

【狂热算法篇】探秘图论之 Floyd 算法:解锁最短路径的神秘密码(通俗易懂版)

&#xff1a; 羑悻的小杀马特.-CSDN博客羑悻的小杀马特.擅长C/C题海汇总,AI学习,c的不归之路,等方面的知识,羑悻的小杀马特.关注算法,c,c语言,青少年编程领域.https://blog.csdn.net/2401_82648291?spm1010.2135.3001.5343 在本篇文章中&#xff0c;博主将带大家去学习所谓的…

【k8s面试题2025】3、练气中期

体内灵气的量和纯度在逐渐增加。 文章目录 在 Kubernetes 中自定义 Service端口报错常用控制器Kubernetes 中拉伸收缩副本失效设置节点容忍异常时间Deployment 控制器的升级和回滚日志收集资源监控监控 Docker将 Master 节点设置为可调度 在 Kubernetes 中自定义 Service端口报…

Ubuntu20.04取消root账号自动登录的方法,触觉智能RK3568开发板演示

Ubuntu20.04默认情况下为root账号自动登录&#xff0c;本文介绍如何取消root账号自动登录&#xff0c;改为通过输入账号密码登录&#xff0c;使用触觉智能EVB3568鸿蒙开发板演示&#xff0c;搭载瑞芯微RK3568&#xff0c;四核A55处理器&#xff0c;主频2.0Ghz&#xff0c;1T算力…

LeetCode | 解锁数组与字符串的秘密:经典题型详解与高效解法

1.理论 1. 1.核心概念 1.1.1.数组(Array) 定义&#xff1a;存储相同数据类型的元素的线性集合。 特点&#xff1a;支持随机访问&#xff08;通过索引&#xff09;;元素存储在连续内存中&#xff0c;支持高效的读写操作。 时间复杂度&#xff1a;访问&#xff1a;O(1);插入…

怎么修复损坏的U盘?而且不用格式化的方式!

当你插入U盘时&#xff0c;若电脑弹出“需要格式化才能使用”提示&#xff0c;且无法打开或读取其中的数据&#xff0c;说明U盘极有可能已经损坏。除此之外&#xff0c;若电脑在连接U盘后显示以下信息&#xff0c;也可能意味着U盘出现问题&#xff0c;需要修复损坏的U盘&#x…

数据结构漫游记:动态实现栈(stack)

嘿&#xff0c;各位技术潮人&#xff01;好久不见甚是想念。生活就像一场奇妙冒险&#xff0c;而编程就是那把超酷的万能钥匙。此刻&#xff0c;阳光洒在键盘上&#xff0c;灵感在指尖跳跃&#xff0c;让我们抛开一切束缚&#xff0c;给平淡日子加点料&#xff0c;注入满满的pa…

w163美食推荐商城

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;原创团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文…

计算机网络 (47)应用进程跨越网络的通信

前言 计算机网络应用进程跨越网络的通信是一个复杂而关键的过程&#xff0c;它涉及多个层面和组件的协同工作。 一、通信概述 计算机网络中的通信&#xff0c;本质上是不同主机中的应用进程之间的数据交换。为了实现这种通信&#xff0c;需要借助网络协议栈中的各层协议&#x…

【Linux】Mysql部署步骤

一、JDK安装配置 在home目录下执行命令&#xff1a;mkdir Jdk 1.将JDK 上传至该文件夹&#xff0c;有些终端工具可以直接上传文件&#xff0c;比如&#xff1a;MobaXterm 可以看到安装包已经上传上来了 2.直接安装 命令&#xff1a;rpm -ivh jdk-8u311-linux-x64.rpm 3.安装成…

归子莫的科技周刊#2:白天搬砖,夜里读诗

归子莫的科技周刊#2&#xff1a;白天搬砖&#xff0c;夜里读诗 本周刊开源&#xff0c;欢迎投稿。 刊期&#xff1a;2025.1.5 - 2025.1.11。原文地址。 封面图 下班在深圳看到的夕阳&#xff0c;能遇到是一种偶然的机会&#xff0c;能拍下更是一种幸运。 白天搬砖&#xff0c;…

你需要什么样的资源隔离?丨TiDB 资源隔离最佳实践

导读 资源隔离是数据库性能优化的重要环节&#xff0c; TiDB 在当前版本已经实现了从数据级隔离到流控隔离的全面升级 &#xff0c;无论是多系统共享集群、复杂负载隔离&#xff0c;还是小型系统整合和 SQL 精细化控制&#xff0c;TiDB 都提供了灵活且高效的解决方案。 本文以…

w162体育馆管理系统

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;原创团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文…

cursor重构谷粒商城02——30分钟构建图书管理系统【cursor使用教程番外篇】

前言&#xff1a;这个系列将使用最前沿的cursor作为辅助编程工具&#xff0c;来快速开发一些基础的编程项目。目的是为了在真实项目中&#xff0c;帮助初级程序员快速进阶&#xff0c;以最快的速度&#xff0c;效率&#xff0c;快速进阶到中高阶程序员。 本项目将基于谷粒商城…

浅谈云计算14 | 云存储技术

云存储技术 一、云计算网络存储技术基础1.1 网络存储的基本概念1.2云存储系统结构模型1.1.1 存储层1.1.2 基础管理层1.1.3 应用接口层1.1.4 访问层 1.2 网络存储技术分类 二、云计算网络存储技术特点2.1 超大规模与高可扩展性2.1.1 存储规模优势2.1.2 动态扩展机制 2.2 高可用性…

服务器数据恢复—EMC存储POOL中数据卷被删除的数据恢复案例

服务器数据恢复环境&故障&#xff1a; EMC Unity 400存储连接了2台硬盘柜。2台硬盘柜上一共有21块硬盘&#xff08;520字节&#xff09;。21块盘组建了2组RAID6&#xff1a;一组有11块硬盘&#xff0c;一组有10块硬盘。 在存储运行过程中&#xff0c;管理员误操作删除了 2组…

【Flink系列】10. Flink SQL

10. Flink SQL Table API和SQL是最上层的API&#xff0c;在Flink中这两种API被集成在一起&#xff0c;SQL执行的对象也是Flink中的表&#xff08;Table&#xff09;&#xff0c;所以我们一般会认为它们是一体的。Flink是批流统一的处理框架&#xff0c;无论是批处理&#xff08…

《Keras 3 神经网络紧凑型卷积转换器(Transformers)》

Keras 3 神经网络紧凑型卷积转换器&#xff08;Transformers&#xff09; 作者&#xff1a;Sayak Paul创建日期&#xff1a;2021/06/30最后修改时间&#xff1a;2023/08/07描述&#xff1a;用于高效图像分类的紧凑型卷积变压器。 &#xff08;i&#xff09; 此示例使用 Keras …

本地部署Web-Check网站检测与分析利器并实现远程访问实时监测

文章目录 前言1.关于Web-Check2.功能特点3.安装Docker4.创建并启动Web-Check容器5.本地访问测试6.公网远程访问本地Web-Check7.内网穿透工具安装8.创建远程连接公网地址9.使用固定公网地址远程访问 前言 本文我们将详细介绍如何在Ubuntu系统上使用Docker部署Web-Check&#xf…

Linux自学指南(学习路线大纲)

Linux入门与进阶指南 目录 第一部分 入门篇 第一章 Linux 系统 1.1 Unix&#xff1a;Linux的“祖师爷” 1.2 Linux 操作系统的诞生与发展历程 1.3 Linux 主要应用领域的归纳 1.4 开源社区的兴起 第二章 如何选择Linux发行版&#xff1f; 2.1 Debian GNU/Linux 2.2 Ubu…