VUE+Spring Flux实现SSE长连接

VUE代码

        // 初始化EventSourceinitEventSource(url) {const token = getAccessToken();const eventSource = new EventSourcePolyfill(url, {headers: {'Authorization': `Bearer ${token}`,'tenant-id': getTenantId(),}});eventSource.onerror = (e) => {console.log("SSE连接错误", e);if (e.readyState === EventSource.CLOSED || eventSource.readyState === EventSource.CONNECTING) {console.log("SSE连接已关闭或正在重连");} else {// 当发生错误时,尝试重新连接if (reconnectAttempts < maxReconnectAttempts) {console.log(`尝试第${reconnectAttempts + 1}次重连`);reconnectAttempts++;setTimeout(() => {eventSource.close(); // 关闭当前连接this.initEventSource(url); // 重新初始化EventSource}, reconnectDelay * reconnectAttempts);} else {console.error("达到最大重连次数,不再尝试重连");}}};eventSource.addEventListener("message", res => {const data = JSON.parse(res.data)if (data.type == 2) {this.unreadCount = data.content;}if (data.type == 1) {this.createNotify(data)}})},

后端采用redis做管道,能够兼容分布式服务

JAVA 监听接口

 @GetMapping(value = "/events", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<String> streamEvents() {Long loginUserId = SecurityFrameworkUtils.getLoginUserId();USER_IDS.add(loginUserId);SseMessageVO heartbeat = new SseMessageVO().setType(SseNotifyTypeEnum.HEARTBEAT.getType()).setUserId(loginUserId).setContent("Heartbeat");return  reactiveRedisOperations.listenToChannel(SseService.getDestination(loginUserId)).map(data -> sendMsg(loginUserId,data.getMessage(),heartbeat)).publishOn(Schedulers.boundedElastic()).doOnSubscribe(subscription -> {// 订阅时发送一次心跳,确认连接heartbeat(heartbeat);});}private String sendMsg(Long loginUserId,String sseMessage,SseMessageVO heartbeat){SseMessageVO sseMessageVO = JSONUtil.toBean(sseMessage, SseMessageVO.class);if (null != sseMessageVO && Objects.equals(sseMessageVO.getUserId(), loginUserId)){return JSONUtil.toJsonStr(sseMessageVO);}return JSONUtil.toJsonStr(heartbeat);}/*** 登录时心跳*/private void heartbeat(SseMessageVO heartbeat) {ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();executorService.schedule(() -> {sseService.publishEventToChannel(heartbeat).subscribe();}, 1, TimeUnit.SECONDS);executorService.shutdown();}/*** 保活*/@PostConstructpublic void heartbeatTimer() {ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();executor.scheduleAtFixedRate(() -> {if (CollectionUtil.isNotEmpty(USER_IDS)){for (Long userId : USER_IDS) {String message = "Heartbeat at " + LocalDateTime.now();SseMessageVO heartbeat = new SseMessageVO().setType(SseNotifyTypeEnum.HEARTBEAT.getType()).setUserId(userId).setContent(message);sseService.publishEventToChannel(heartbeat).subscribe();}}}, 0, 10, TimeUnit.SECONDS);}

JAVA 提交数据服务

@Component
public class SseService {@Resourceprivate ReactiveRedisOperations<String, String> reactiveRedisOperations;private static final String DESTINATION = "event-channel-user:";/*** 获取指定通道* @param userId* @return*/public static String getDestination(Long userId){return DESTINATION+userId;}/*** 推送事件到通道* @param sseMessageVO* @return*/public Mono<Long> publishEventToChannel(SseMessageVO sseMessageVO) {return reactiveRedisOperations.convertAndSend(getDestination(sseMessageVO.getUserId()), JSONUtil.toJsonStr(sseMessageVO));}}

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

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

相关文章

C# 下sendmessage和postmessage的区别详解与示例

文章目录 1、SendMessage2、PostMessage3、两者的区别&#xff1a; 总结 在C#中&#xff0c;SendMessage和PostMessage是两个用于Windows编程的API&#xff0c;它们用于向窗口发送消息。这两个方法都位于System.Windows.Forms命名空间中&#xff0c;通常用于自动化Windows应用程…

GitHub:现代软件开发的协作平台

引言 在现代软件开发中&#xff0c;协作工具的选择至关重要。GitHub作为全球最大的代码托管平台&#xff0c;已经成为开发者们不可或缺的工具。自2008年成立以来&#xff0c;GitHub不仅改变了代码托管和协作的方式&#xff0c;还在开源软件的发展中扮演了重要角色。本文将详细…

科普文:分布式系统的架构设计模式

一、分布式架构基本概念 分布式架构是一种计算机系统设计方法&#xff0c;它将一个复杂的系统划分为多个自治的组件或节点&#xff0c;并通过网络进行通信和协作。每个组件或节点在功能上可以相互独立&#xff0c;但又能够通过消息传递或共享数据来实现协同工作。分布式架构主要…

值传递与引用传递:深入理解Java中的变量赋值和参数传递机制

在Java中&#xff0c;理解值传递&#xff08;值拷贝&#xff09;与引用传递&#xff08;地址拷贝&#xff09;之间的区别对于正确处理数据结构和对象至关重要。本文将通过示例代码深入探讨这两种机制&#xff0c;并解释它们如何影响程序的行为。 值传递&#xff08;值拷贝&…

获取脚本执行时间

在运行一些脚本时&#xff0c;时间会过期&#xff0c;这时就需要重新更新token&#xff0c;下面做了一个demo判断时间是否过期 import datetime import time starttimedatetime.datetime.now() # 时间进行格式化 starttimestarttime.strftime("%Y-%m-%d %H:%M:%S") …

高效利用iCloud指南

高效利用 iCloud 需要了解其各种功能和最佳实践&#xff0c;以充分发挥其云存储和同步能力。以下是详细的指南&#xff1a; ### 1. 设置和管理 iCloud 存储 **初始设置** - 确保在所有设备&#xff08;iPhone、iPad、Mac&#xff09;上使用同一 Apple ID 登录 iCloud。 - 在设…

iPaaS丨企业应用及数据集成的重要性和挑战

在激烈的市场竞争中&#xff0c;企业服务总线和数据总线扮演着企业神经网络的角色&#xff0c;它们将不同的业务部门、系统以及数据紧密相连&#xff0c;保障信息流通无阻&#xff0c;实现资源的高效分配。这样的集成不仅提高了企业的运营效率&#xff0c;还增强了企业的适应性…

虚拟机因断电进入./#状态解决办法

现象&#xff1a; 解决&#xff1a;先查看错误日志&#xff1a;journalctl -p err -b查看自己虚拟机中标黄部分的名字 之后运行&#xff1a;xfs_repair -v -L /dev/sda #这里sda用你自己标黄的 最后重启 reboot 即可。

使用Dockerfile和ENTRYPOINT运行Python 3脚本

在Docker中运行Python 3脚本是一种常见的部署应用程序的方式。通过使用Dockerfile&#xff0c;我们可以定义一个包含Python环境和应用程序的Docker镜像。在Dockerfile中&#xff0c;我们可以使用ENTRYPOINT指令来指定当容器启动时应该运行的命令。 **一、创建Dockerfile** 首先…

在Linux上运行macOS:深度解析OSX-KVM项目

在Linux上运行macOS&#xff1a;深度解析OSX-KVM项目 在现代开发和测试环境中&#xff0c;能够在不同操作系统之间无缝切换是至关重要的。对于开发者而言&#xff0c;如何在Linux系统上运行macOS一直是一个挑战。然而&#xff0c;OSX-KVM项目为我们提供了一种高效的解决方案&a…

R包:ggsci期刊配色

介绍 不同期刊配色大多数时候不一样&#xff0c;为了更好符合期刊图片颜色的配色&#xff0c;有人开发了ggsci这个R包。它提供以下函数&#xff1a; scale_color_palname() scale_fill_palname() 对应不同期刊的color和fill函数。 导入数据R包 library("ggsci")…

如何一起解压缩多个小压缩包unzip multiprt zip file

这个问题有两种解读&#xff0c;一种是需要解压这个文件夹里面的所有zip文件。另一个是压缩文件时候存成了多个part&#xff0c;需要一起解压缩。 环境 Ubuntu22.04 解决方法 解压当前文件夹所有zip文件 unzip your/folder/*.zip解压同一压缩文件的多个part sudo apt ins…

SpringBoot使用@RestController处理GET和POST请求

在Spring MVC中&#xff0c;RestController注解的控制器类可以处理多种HTTP请求方法&#xff0c;包括GET和POST。这些请求方法通过特定的注解来映射&#xff0c;比如GetMapping用于GET请求&#xff0c;PostMapping用于POST请求。这些注解是RequestMapping的特定化版本&#xff…

2024年全面导入APS系统:提升工厂生产效率的策略

在快速变化的市场环境中&#xff0c;急单、插单、订单设计变更、订单交期变更、订单取消、供应链移动等问题已经是制造业时时刻刻都在面对的问题&#xff0c;在订单量下降的市场环境下&#xff0c;企业本身的业务工作反而越来越忙碌。在此背景下&#xff0c;当今制造业企业亟需…

JavaScript高级程序设计(第四版)--学习记录之函数(下)

函数内部 ES5中,函数内部存在两个特殊的对象:arguments和this。ES6新增了new.target属性。 arguments arguments对象其实还有一个callee属性,是一个指向arguments对象所在函数的指针。 function fb(num){ if(num<=1){ return 1; }else{ return num * fb(num-1); } }/*这个…

【pytorch24】Visdom可视化

TensorboardX pytorch有一个工具借鉴了tensorboard pip install tensorboardX 有查看变量的数值、监听曲线等功能 如何使用 新建SummaryWriter()实例 要把监听的数据&#xff0c;比如说要监听dummy_s1[0]&#xff08;y 坐标&#xff09;存放到data/scalar1中&#xff0c;…

ASPICE是汽车软件开发中的质量保证流程

复杂的汽车系统对软件的质量和可靠性提出了极高的要求。为了确保汽车软件的高质量和可靠性&#xff0c;ASPICE&#xff08;Automotive SPICE&#xff0c;汽车软件过程改进和能力确定&#xff09;流程应运而生。本文将对ASPICE流程进行详细介绍。 一、ASPICE概述 ASPICE是汽车行…

【React】React18 Hooks 之 useContext

目录 useContext1、Provider和 useContext2、Provider 和Consumer3、Provider 嵌套4、React.createContext提供的Provider和class的contextType属性5、读、写Context&#xff08;1&#xff09;父组件修改Context&#xff08;2&#xff09;子组件修改Context 好书推荐 useContex…

NPDP有什么价值?究竟值不值得去考?

NPDP其实就是产品经理国际资格认证&#xff0c;是美国产品开发管理协会发起的&#xff0c;集理论、方法和实践一体&#xff0c;在新产品开发方面有一个很全面的知识体系。是国际公认的新产品开发专业认证&#xff0c;具有权威性。 NPDP能够很好地帮你在做新产品的道路上少走弯…

【已解决】腾讯云安装了redis,但是本地访问不到,连接不上

汇总了我踩过的所有问题。 查看配置文件redis.conf 1、把bind 127.0.0.1给注释掉&#xff08;前面加个#就是&#xff09;或者改成bind 0.0.0.0&#xff0c;因为刚下载时它是默认只让本地访问。&#xff08;linux查找文档里的内容可以输入/后面加需要匹配的内容&#xff0c;然后…