springboot+vue+SseEmitter数据流推送实战

业务场景

SseEmitter介绍

SseEmitter 是 Spring Boot 中用于实现服务器发送事件(Server-Sent Events, SSE)的一种机制。SSE 允许服务器向客户端推送实时数据,而不需要客户端频繁地发起请求。这对于实现实时通知、更新等场景非常有用。

SseEmitter与WebSocket区别

1. 单向 vs 双向通信

  • SSE (Server-Sent Events):
    • 单向通信: SSE 只支持服务器向客户端推送数据,客户端不能通过同一个连接向服务器发送数据。
    • 适用场景: 适用于只需要服务器向客户端推送数据的场景,如实时通知、股票行情、新闻更新等。
  • WebSocket:
    • 双向通信: WebSocket 支持全双工通信,服务器和客户端都可以通过同一个连接发送数据。
    • 适用场景: 适用于需要双向实时通信的场景,如在线聊天、多人协作编辑、实时游戏等。

2. 连接建立

  • SSE:
    • 基于 HTTP: SSE 使用 HTTP 协议建立连接,客户端通过普通的 HTTP GET 请求连接到服务器。
    • 简单性: 建立连接的过程相对简单,不需要额外的握手步骤。
  • WebSocket:
    • 基于 WebSocket 协议: WebSocket 使用独立的协议,需要通过 WebSocket 握手建立连接。
    • 复杂性: 建立连接的过程稍微复杂一些,需要客户端和服务器进行握手协商。

3. 数据格式

  • SSE:
    • 文本数据: SSE 只能传输文本数据,数据格式通常是简单的文本或 JSON。
    • 事件类型: 支持自定义事件类型,可以通过 event 字段指定。
  • WebSocket:
    • 二进制/文本数据: WebSocket 支持传输二进制数据和文本数据,灵活性更高。
    • 帧结构: 数据以帧的形式传输,支持多种子协议。

4. 连接保持

  • SSE:
    • 长轮询: SSE 连接在数据发送完毕后会自动关闭,客户端需要重新建立连接。可以通过设置 retry 字段来控制重连时间。
    • 自动重连: 浏览器会自动处理重连,但可能会有短暂的中断。
  • WebSocket:
    • 持久连接: WebSocket 连接一旦建立,会一直保持打开状态,除非显式关闭或发生错误。
    • 手动重连: 需要手动处理重连逻辑。

5. 浏览器支持

  • SSE:
    • 广泛支持: SSE 在现代浏览器中得到了广泛支持,包括 Chrome、Firefox、Safari 和 Edge。
    • 兼容性: 一些较旧的浏览器可能不支持 SSE,但可以通过 polyfill 来实现兼容。
  • WebSocket:
    • 广泛支持: WebSocket 在现代浏览器中也得到了广泛支持,包括 Chrome、Firefox、Safari 和 Edge。
    • 兼容性: 一些较旧的浏览器可能不支持 WebSocket,但可以通过 Flash 或其他技术来实现兼容。

6. 性能和资源消耗

  • SSE:
    • 轻量级: SSE 的实现相对简单,资源消耗较低。
    • 服务器负载: 由于连接会在数据发送完毕后关闭,服务器负载相对较小。
  • WebSocket:
    • 高性能: WebSocket 由于支持持久连接,可以实现更低的延迟和更高的性能。
    • 服务器负载: 由于连接一直保持打开状态,服务器需要管理更多的连接,可能会增加服务器负载。

总结

  • SSE 适用于简单的、单向的实时数据推送场景,实现简单,资源消耗低。
  • WebSocket 适用于复杂的、双向的实时通信场景,支持二进制数据,性能高,但实现复杂,资源消耗较高。
    选择哪种技术取决于你的具体需求。如果你只需要服务器向客户端推送数据,且数据量不大,SSE 是一个很好的选择。如果你需要双向通信或传输大量数据,WebSocket 更适合。

入门教程

https://www.ruanyifeng.com/blog/2017/05/server-sent_events.html

实战案例

添加依赖

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

编写Controller

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;@RestController
@RequestMapping("/sse")
public class SseController {private final ExecutorService executorService = Executors.newFixedThreadPool(10);@GetMapping(value = "/connect", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public SseEmitter connect() {SseEmitter sseEmitter = new SseEmitter(Long.MAX_VALUE); // 设置超时时间为 Long.MAX_VALUE// 异步处理消息发送executorService.submit(() -> {try {for (int i = 1; i <= 10; i++) {sseEmitter.send(SseEmitter.event().id(String.valueOf(i)).name("greeting").data("Hello, message " + i));Thread.sleep(1000); // 模拟延迟}sseEmitter.complete(); // 完成发送} catch (IOException | InterruptedException e) {sseEmitter.completeWithError(e); // 发生错误时完成}});return sseEmitter;}
}

编写前端页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SSE Example</title>
</head>
<body><h1>Server-Sent Events Example</h1><ul id="messages"></ul><script>const eventSource = new EventSource('/sse/connect');eventSource.onmessage = function(event) {const messages = document.getElementById('messages');const li = document.createElement('li');li.textContent = 'Message: ' + event.data;messages.appendChild(li);};eventSource.onerror = function(error) {console.error('EventSource failed:', error);eventSource.close();};</script>
</body>
</html>

测试效果

在这里插入图片描述

踩坑指南

SpringBoot项目中Shrio报No SecurityManager解决办法

https://blog.csdn.net/ning_yi/article/details/126174262

SseEmitter event-stream多了双引号问题排除

https://blog.csdn.net/czqbaifnxkj/article/details/138123289

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

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

相关文章

阿里云 DevOps 资源安全扫描实践

随着企业上云进程的加速&#xff0c;云资源的使用量日益增长&#xff0c;云环境中资源的安全性和稳定性成为了企业业务运营的关键要素 面对多样化的云资源和复杂的应用场景&#xff0c;传统的安全管理手段已无法完全满足企业日益严苛的安全需求。为了确保云上资源的安全性&…

python之sklearn--鸢尾花数据集之数据降维(PCA主成分分析)

python之sklearn–鸢尾花数据集之数据降维(PCA主成分分析) sklearn库&#xff1a;Scikit - learn&#xff08;sklearn&#xff09;是一个用于机器学习的开源 Python 库。它建立在 NumPy、SciPy 和 matplotlib 等其他科学计算库之上&#xff0c;为机器学习的常见任务提供了简单…

sourceInsight常用设置和功能汇总(不断更新)(RGB、高亮、全路径、鼠标、宏、TODO高亮)

文章目录 必开配置设置背景颜色护眼的RGB值&#xff1f;sourceInsight4.0中如何设置选中某个单词以后自动高亮的功能&#xff1f;sourceinsight中输入设置显示全路径&#xff1f; 常用sourceInsight4.0中文乱码怎么解决&#xff0c;注意事项是什么&#xff1f;如何绑定鼠标中键…

oracle ogg学习和ogg常见变更操作

oracle ogg学习和ogg常见变更操作 OGG&#xff08;Oracle GoldenGate&#xff09; OGG 是一种基于日志的结构化数据复制软件&#xff0c;它通过解析源数据库在线日志或归档日志获得数据的增删改变化&#xff08;数据量只有日志的四分之一左右&#xff09; OGG 能够实现大量交…

游戏引擎学习第19天

介绍 这段内容描述了开发者在进行游戏开发时&#xff0c;对于音频同步和平台层的理解和调整的过程。以下是更详细的复述&#xff1a; 开发者表达了他希望今天继续进行的工作内容。他提到&#xff0c;昨天他讲解了一些关于音频的内容&#xff0c;今天他想稍微深入讲解一下他正…

Flink错误:一historyserver无法启动,二存在的文件会报错没有那个文件或目录

一.historyserver无法启动 historyserver执行了启动命令后却没有启动&#xff0c;而且也没有报错&#xff0c;如果日志无法启动的话网页8082是无法访问的 只能去查看日志 去flink的log文件查看日志&#xff1a; 发现应该是缺包了&#xff0c;导入jar包后可以解决 &#xff1a…

归一化/标准化对神经网络的训练是否有影响?

一、背景 归一化&#xff08;Normalization&#xff09;和标准化&#xff08;Standardization&#xff09;是数据预处理中的两种常见技术&#xff0c;旨在调整数据的范围和分布&#xff0c;以提高机器学习模型或者深度学习模型的性能和训练速度。虽然它们的目标相似&#xff0c…

Redis、TongRDS 可视化工具使用之 Redis Insight

题外话&#xff1a;除了可以连接 redis&#xff0c;也可以用来连接 TongRDS 1&#xff09;官网下载 Redis Insight 2&#xff09;安装 3&#xff09;连接 4&#xff09;使用 这里只是给一个使用例子

oracle查看锁阻塞-谁阻塞了谁

一 模拟锁阻塞 #阻塞1 一个会话正在往一个大表写入大量数据的时候&#xff0c;另一个会话加字段&#xff1a; #会话1 #会话2 会话2被阻塞了。 #阻塞2 模拟一个会话update一条记录&#xff0c;没提交。 另一个会话也update这一条记录&#xff1a; 会话2被阻塞了。 二 简单查…

django基于django的民族服饰数据分析系统的设计与实现

摘 要 随着网络科技的发展&#xff0c;利用大数据分析对民族服饰进行管理已势在必行&#xff1b;该平台将帮助企业更好地理解服饰市场的趋势&#xff0c;优化服装款式&#xff0c;提高服装的质量。 本文讲述了基于python语言开发&#xff0c;后台数据库选择MySQL进行数据的存储…

STM32单片机CAN总线汽车线路通断检测-分享

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 随着汽车电子技术的不断发展&#xff0c;车辆通信接口在汽车电子控…

golang对日期格式化

1.对日期格式化为 YYYY-mm-dd, 并且没有数据时&#xff0c;返回空 import ("encoding/json""time" )type DateTime time.Timetype SysRole struct {RoleId int64 gorm:"type:bigint(20);primary_key;auto_increment;角色ID;" json:&quo…

MySQL系列之数据授权(privilege)

导览 前言Q&#xff1a;如何对MySQL数据库进行授权管理一、MySQL的“特权”1. 权限级别2. 权限清单 二、授权操作1. 查看权限2. 分配权限3. 回收权限 结语精彩回放 前言 看过博主上一篇的盆友&#xff0c;可以Get到一个知识点&#xff1a;数据授权&#xff08;eg&#xff1a;g…

项目进度计划表:详细的甘特图的制作步骤

甘特图&#xff08;Gantt chart&#xff09;&#xff0c;又称为横道图、条状图&#xff08;Bar chart&#xff09;&#xff0c;是一种用于管理时间和任务活动的工具。 甘特图由亨利劳伦斯甘特&#xff08;Henry Laurence Gantt&#xff09;发明&#xff0c;是一种通过条状图来…

【Redis】Redis实现的消息队列

一、用list实现【这是数据类型所以支持持久化】 消息基于redis存储不会因为受jvm内存上限的限制&#xff0c;支持消息的有序性&#xff0c;基于redis的持久化机制&#xff0c;只支持单一消费者订阅&#xff0c;无法避免消息丢失。 二、用PubSub【这不是数据类型&#xff0c;是…

Linux登录指令last详解

引言 在Linux系统中&#xff0c;了解用户登录记录是系统管理和安全审计的重要任务之一。last指令作为Linux系统中用于检索和展示用户登录信息的工具&#xff0c;扮演着至关重要的角色。本文将详细介绍last指令的定义、架构、原理、企业应用以及常见的命令体系&#xff0c;帮助…

CSP-X2024山东小学组T2:消灭怪兽

题目链接 题目名称 题目描述 怪兽入侵了地球&#xff01; 为了抵抗入侵&#xff0c;人类设计出了按顺序排列好的 n n n 件武器&#xff0c;其中第 i i i 件武器的攻击力为 a i a_i ai​&#xff0c;可以造成 a i a_i ai​ 的伤害。 武器已经排列好了&#xff0c;因此不…

【操作系统笔记】目录

【操作系统笔记】操作系统框架https://blog.csdn.net/Resurgence03/article/details/142624262 【操作系统笔记】CPU管理https://blog.csdn.net/Resurgence03/article/details/142621526 【操作系统笔记】内存管理https://blog.csdn.net/Resurgence03/article/details/142669…

用 Python 与 Turtle 创作属于你的“冰墩墩”!

用 Python 与 Turtle 创作属于你的“冰墩墩”&#xff01; &#x1f980; 前言 &#x1f980;&#x1f40b; 效果图 &#x1f40b;&#x1f409; 代码 &#x1f409; &#x1f980; 前言 &#x1f980; 冰墩墩是2022年北京冬季奥林匹克运动会的官方吉祥物。以熊猫为原型&#x…

C++将整形数据转换为字符串

在 C 中&#xff0c;将整数转换为字符串有多种方法&#xff0c;以下是几种常见的方式&#xff1a; 1. 使用 std::to_string 函数&#xff08;C11 及以后版本可用&#xff09; 函数介绍&#xff1a;std::to_string 是 C 标准库提供的一个非常方便的函数&#xff0c;它位于 <…