SpringBoot整合SSE,实现后端主动推送DEMO

前言

说起服务端主动推送,大家第一个想到的一定是WEBSOCKET 。

作为软件工程师,不能无脑使用一种技术,要结合实际情况,择优选取。

SSE(Server-Sent Events)相比于WEBSOCKET 

1、轻量化、兼容性 基于传统的HTTP协议,所以浏览器兼容性比较好

2、 只支持单向通讯。(服务器->客户端)

服务端测试代码

@RestController
public class SseController {private final ConcurrentHashMap<String, SseEmitter> emitters = new ConcurrentHashMap<>();@GetMapping("/subscribe/{id}")@CrossOrigin(origins = "*")public SseEmitter subscribe(@PathVariable String id) {SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);emitters.put(id, emitter);emitter.onCompletion(() -> emitters.remove(id));emitter.onError(e -> emitters.remove(id));System.out.println(emitter);return emitter;}@GetMapping("/unbind/{id}")public R deleteItem(@PathVariable String id) {this.emitters.remove(id);return R.ok(true);}@GetMapping("test/send")public void test(){this.broadcastMessage("hello world");}@Asyncpublic void broadcastMessage(String message) {List<String> keysToDelete = new ArrayList<>();emitters.forEach((k, v) -> {try {v.send(message);} catch (Throwable t) {keysToDelete.add(k);}});keysToDelete.forEach(emitters::remove);}
}

这边是群发消息,也可以根据特定id,发送消息,发送消息可采用异步方式。

订阅消息接口需 支持跨域

设置SSE过期时间为Long的max_value

当建立连接后, 访问test/send 发送hello world

前端代码

<template><div id="app"><div>{{chartStr}}</div><div v-for="(item,index) in sseMessage" :key="index">{{item}}</div></div>
</template>
<script>export default {name: 'App',data() {return {sseMessage: [],chartStr: '',eventSource: undefined,}},mounted() {this.getChartStr()this.initSSE()},beforeUnload() {this.unbindSSE();},methods: {/*** 初始化服务器发送事件(SSE)连接** 此方法创建一个新的 EventSource 对象,连接到后端服务器的指定 URL,* 并添加一个 message 事件监听器,用于接收服务器发送的消息。*/initSSE() {// 创建一个SSE对象,连接到后端接口this.eventSource = new EventSource("http://192.168.0.198:8089/subscribe/" + this.chartStr);// 监听message事件,接收后端发送的消息// this.eventSource.addEventListener("message", (event) => {//   //将返回data插入元素   //   this.sseMessage.push(event.data)// });this.eventSource.onmessage = (event) => {this.sseMessage.push(event.data)};this.eventSource.onerror = function (event) {if (event.target.readyState === EventSource.CLOSED) {console.log('Connection closed');} else {console.error('Error occurred', event);}}},/*** 取消订阅 SSE 事件源并解绑图表** 这个方法首先检查是否存在有效的 SSE 对象。如果存在,它将关闭这个 SSE 连接。*/unbindSSE() {if (this.eventSource) {this.eventSource.close();}fetch('http://192.168.0.198:8089/unbind/' + this.chartStr, {method: 'GET'}).catch(error => {console.error('Error unsubscribing:', error);});},/*** 获取唯一的图表字符串** 此方法用于获取一个随机生成的、唯一的图表字符串。* */getChartStr() {let array = new Uint32Array(1);crypto.getRandomValues(array);let randomHex = array[0].toString(16);let paddedHex = randomHex.padStart(8, '0'); // 确保32位长度this.chartStr = paddedHex},},}
</script>
<style>#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;}nav {padding: 30px;}nav a {font-weight: bold;color: #2c3e50;}nav a.router-link-exact-active {color: #42b983;}
</style>

测试

效果如下

拓展

EventSource

EventSource 接口提供了一个简单的 API 来接收服务器发送的事件。一旦创建了 EventSource 实例并指向一个 URL,浏览器就会尝试与服务器建立一个持久连接。

text/event-stream

text/event-stream 是一种 MIME 类型,用于描述 Server-Sent Events 的数据格式。服务器使用这种格式向客户端发送事件。每个事件由以下几部分组成:

  • data: : 必须包含的数据字段,后面跟着实际的事件数据。
  • event: : 可选的事件类型,如果指定了这个字段,onmessage 事件处理器将收到一个 event 属性,该属性包含了这个事件类型的值。
  • id: : 可选的字段,用来标识事件的序列号,客户端可以使用它来检测丢失的事件。
  • retry: : 可选的字段,表示在连接中断后重连前的延迟时间(以毫秒为单位)。

通俗解释一下

EventSource 就像是你坐在那里,服务员(服务器)主动把咖啡(信息)端到你的桌子上(浏览器)。你不需要起身询问。

text/event-stream 其实就相当于服务员的托盘,怎么个方式给你把咖啡(信息)送过来。

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

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

相关文章

pytorch学习(十二)c++调用minist训练的onnx模型

在实际使用过程中&#xff0c;使用python速度不够快&#xff0c;并且不太好嵌入到c程序中&#xff0c;因此可以把pytorch训练的模型转成onnx模型&#xff0c;然后使用opencv进行调用。 所需要用到的库有&#xff1a; opencv 1.完整的程序如下 import torch from torch impo…

零基础STM32单片机编程入门(十七)SPI总线详解及RC522-NFC刷卡模块实战含源码

文章目录 一.概要二.SPI总线基本概念1.SPI总线内部框图2.总体特征3.通讯时序 三.RC522介绍1.NFC基本介绍2.RC522模块基本特点3.RC522模块原理图4.RC522模块SPI通讯时序 四.RC522模块读卡实验五.CubeMX工程源代码下载六.小结 一.概要 SPI总线是由Motorola公司提出&#xff0c;是…

05_解封装和解码

1. 基本概念 容器就是一种文件格式&#xff0c;比如flv、mkv、mp4等。包含下面5种流以及文件头信息。 流是一种视频数据信息的传输方式&#xff0c;5种流&#xff1a;音频&#xff0c;视频&#xff0c;字幕&#xff0c;附件&#xff0c;数据。 包在ffmpeg中代表已经编码好的一…

FPGA实验3:D触发器设计

一、实验目的及要求 熟悉Quartus II 的 VHDL 文本设计简单时序电路的方法&#xff1b; 掌握时序电路的描述方法、波形仿真和测试&#xff0c;特别是时钟信号的特性。 二、实验原理 运用Quartus II 集成环境下的VHDL文本设计方法设计简单时序电路——D触发器&#xff0c;依据…

三相PWM整流器滞环电流控制仿真matlab simulink

1、内容简介 略 88-可以交流、咨询、答疑 2、内容说明 略 三相&#xff30;&#xff37;&#xff2d;整流器已广泛应用工业与电气控制领域电流控制技术决定着三相&#xff30;&#xff37;&#xff2d;整流器系统的控制性能。综合比 较了各种电流控制方法应用较多的滞环比较…

C++ 类和对象 构造函数(下)

一 初始化列表&#xff1a; 1.1 构造函数体赋值&#xff1a; 在C中&#xff0c;构造函数用于创建对象并赋予其初始值。通常&#xff0c;我们可以在构造函数体内对成员变量进行赋值&#xff1a; class Date { public:Date(int year, int month, int day) {_year year;_mont…

golang 解压带密码的zip包

目录 Zip文件详解ZIP 文件格式主要特性常用算法Zip格式结构图总览Zip文件结构详解数据区本地文件头文件数据文件描述 中央目录记录区&#xff08;核心目录记录区 &#xff09;中央目录记录尾部区 压缩包解压过程方式1 通过解析中央目录区来解压方式2 通过读取本地文件头来解压两…

[言简意赅] Matlab生成FPGA端rom初始化文件.coe

&#x1f38e;Matlab生成FPGA端rom初始化文件.coe 本文主打言简意赅。 函数源码 function gencoeInitialROM(width, depth, signal, filepath)% gencoeInitialROM - 生成 Xilinx ROM 初始化格式的 COE 文件%% 输入参数:% width - ROM 数据位宽% depth - ROM 数据深度% s…

heic文件怎么转换成jpg?上百份文件转换3秒就能搞定(办公必备)

heic和jpg是两种不同的图片格式&#xff0c;平时整理图片素材时&#xff0c;如果需要将heic转为jpg格式&#xff0c;那么可以使用相关的heic图片转换工具。 ​ 为什么要将heic文件转换成jpg&#xff1f;虽然HEIC格式具有很多优点&#xff0c;但是目前并不是所有设备和应用程序…

好玩模拟游戏推荐:缺氧:眼冒金星 单机游戏分享

《缺氧》 是一款太空殖民模拟游戏。 在外太空岩深处&#xff0c;你手下的勤劳开拓者们需要熟练掌握科技&#xff0c;战胜新的陌生生命形式&#xff0c;以及利用难以置信的太空技术来生存。甚至&#xff0c;还有可能繁荣起来。 建立广阔的基地以及探索生存所需的资源&#xff1…

服务攻防_01数据库安全RedisCouchdbH2database

一、数据库-Redis-未授权RCE&CVE 1、未授权访问&#xff1a;CNVD-2015-07557 &#xff08;1&#xff09;漏洞描述 Redis默认情况下会绑定在6379端口 如果没有采取相关策略&#xff08;如添加防火墙规则阻止非信任来源IP访问&#xff09;&#xff0c;会将Redis暴露在公网…

HTML5实现好看的天气预报网站源码

文章目录 1.设计来源1.1 获取天气接口1.2 PC端页面设计1.3 手机端页面设计 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板&#xff0c;程序开发&#xff0c;在线开发&#xff0c;在线沟通 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_4…

揭秘电子画册制作流程,打造独一无二的作品

在这个数字化的时代&#xff0c;电子画册已经成为了展示个人创意和品牌形象的重要工具。它不仅能够呈现出丰富多彩的内容&#xff0c;还能够实现互动性和传播性&#xff0c;吸引众多观众的目光。然而&#xff0c;许多人对于电子画册的制作流程仍然感到陌生。本文将揭秘电子画册…

企业VR展厅如何提升品牌形象,生动展示产品和企业文化?

一、提升产品展示效果 1、全方位展示产品细节 企业VR展厅可以通过3D建模和虚拟现实技术&#xff0c;将产品的每一个细节清晰地展示出来。客户可以全方位查看产品的外观、结构和功能。这种身临其境的体验远比传统的平面展示更加生动和详细。 细节展示&#xff1a;客户可以通过…

Ubuntu22 Qt6.6 ROS 环境搭建

Ubuntu22.04; Qt6.6; Qt Creator 13.01; ROS2 1. 安装 Qt ROS 插件 1.下载地址&#xff1a; https://github.com/ros-industrial/ros_qtc_plugin/releases 选择对应 Qt Creator 版本的安装包。 2. Qt Creator中&#xff0c;“Help - 关于插件”–>“install Plugin…

一个模板实现的工厂的编译问题的解决。牵扯到重载、特化等

简介 在一个项目里&#xff0c;调用了第三封的库&#xff0c;这个库里面有个类用的很多&#xff0c;而且其构造函数至少有6个&#xff0c;并且个人感觉还不够多。根据实际使用&#xff0c;还得增加一些。 需求 1、增加构造函数&#xff0c;比如除了下面的&#xff0c;还增加…

Gateway源码分析:路由Route、断言Predicate、Filter

文章目录 源码总流程图说明GateWayAutoConfigurationDispatcherHandlergetHandler()handleRequestWith()RouteToRequestUrlFilterReactiveLoadBalancerClientFilterNettyRoutingFilter 补充知识适配器模式 详细流程图 源码总流程图 在线总流程图 说明 Gateway的版本使用的是…

01常见控件

文章目录 控件各种响应事件获取控件类型CButton/CheckBox&#xff08;多选&#xff09;/RadioButton&#xff08;单选&#xff09;EditControl&#xff08;文本编辑框&#xff09;/ ListBox&#xff08;列表文本框&#xff09;/ComboBox&#xff08;可下拉列表&#xff09;Prog…

【Ubuntu】Ubuntu系统镜像

清华镜像源 Index of /ubuntu-releases/ | 清华大学开源软件镜像站 | Tsinghua Open Source MirrorIndex of /ubuntu-releases/ | 清华大学开源软件镜像站&#xff0c;致力于为国内和校内用户提供高质量的开源软件镜像、Linux 镜像源服务&#xff0c;帮助用户更方便地获取开源软…

stm32学习:(寄存器2)GPIO总体说明

目录 GPIO的主要特点 GPIO的8种工作模式 GPIO电路结构 GPIO输出模式 输出流程 复用输出模式 GPIO输入模式 输入流程 模拟输入流程 GPIO相关的7个寄存器 GPIOx_CRL GPIOx_CRH GPIOx_IDR GPIOx_ODR GPIOx_BSRR GPIOx_BRR GPIOx_LCKR 实例 三个灯流水灯 main.…