当前位置: 首页 > news >正文

SSE实时数据推送

创建SSE连接对象后可以实时的根据信息对信息进行推送。一般在系统中我们会采用Map存储用户的信息。

// 5. 创建SSE连接,设置超时时间为1小时 SseEmitter emitter = new SseEmitter(60 * 60 * 1000L); //如果创建时时间设置为0L表示改连接永不超时只能通过监听器删除或者通过用户手动删除

当通过Sse连接到客户端时可以通过不同的API确保系统的正常使用。通过在API中设置Sse的策略,自由配置当Sse出现异常时的策略。

emitter.onCompletion(() -> { emitters.remove(connectionKey); System.out.println("SSE连接完成,用户: " + userName); }); //如果连接超时则调用改内部方法 emitter.onTimeout(() -> { emitters.remove(connectionKey); System.out.println("SSE连接超时,用户: " + userName); }); //Sse连接发生异常后调用内部方法 emitter.onError((ex) -> { emitters.remove(connectionKey); System.out.println("SSE连接错误,用户: " + userName + ", 错误: " + ex.getMessage()); });

通过调用SseEmitter对象的send方法向客户端进行发送数据,调用completeWithError可以进行关闭连接。关闭连接时要进行查看Map中存储的连接是否被删除防止因为未删除而造成无效连接的资源占用。

通过sse连接循环发送不同的数据信息:

循环发送数据我们可以既可以通过创建实时调度线程池进行实现也可以通过springboot中的任务调度注解搭配SseEmitter的reconnectTime方法进行循环发送数据。

任务调度线程池:

// 启动定时任务,每30秒推送一次数据 scheduler.scheduleAtFixedRate(this::broadcastData, 0, REFRESH_INTERVAL, TimeUnit.SECONDS);

通过springboot中的任务调度搭配SseEmitter的reconnectTime方法进行循环发送数据:

@Scheduled(cron = "0/30 * * * * *")//间隔30秒发送一次数据 // 发送连接成功事件,发送成功后间隔1秒才可以再次发送 SseEmitter.event().reconnectTime(1000);
Sse连接心跳检测:

当我们创建了永久不超时的SSe连接后如果客户端并未及时关闭或长时间占用系统资源我们可以通过创建心跳检测的心跳检测任务进行移除该连接

@Scheduled(cron = "0/30 * * * * *") public void SseHeartbeatCheck() { if (emitters.size() > 0){ //记录要删除的连接 List<String> toRemove = new ArrayList<>(); long currentTime = System.currentTimeMillis(); for (Map.Entry<String, SseEmitter> entry : emitters.entrySet()) { SseEmitter emitter = entry.getValue(); try { //心跳检测包 HashMap<String, Object> heart = new HashMap<>(); heart.put("type", "heartbeat"); heart.put("timestamp", currentTime); heart.put("serverTime", new java.util.Date()); SseEmitter.SseEventBuilder heartbeat = SseEmitter.event() .name("heartbeat") .id(String.valueOf(currentTime)) .data(heart); emitter.send(heartbeat); }catch (Exception e){ //移除异常连接 toRemove.add(entry.getKey()); } } //批量移除异常连接 toRemove.stream().forEach(E -> { SseEmitter emitter = emitters.get(E); if (emitter != null) { emitter.complete(); emitters.remove(emitter); } }); } }
http://www.jsqmd.com/news/301245/

相关文章:

  • YOLOv11模型压缩实战:轻量化部署降低GPU资源消耗
  • unet image Face Fusion成本太高?弹性GPU按需计费部署实战
  • 开关电源电路图解析:全面讲解反激式拓扑结构
  • Open-AutoGLM与传统RPA对比:智能规划能力实战评测
  • GPEN离线推理如何实现?预下载权重与缓存路径配置详解
  • 革新性视频播放增强工具:重构JAVDB观影体验的技术实践
  • 数据库概述
  • 克拉泼振荡电路Multisim仿真图解说明
  • 高并发系统的7大架构优化策略:从瓶颈诊断到性能倍增的实战指南
  • Z-Image-Turbo如何批量生成?Python脚本扩展部署案例详解
  • vivado安装教程与工业HMI联动配置方法
  • Z-Image-Turbo部署卡顿?CUDA 12.4环境优化实战案例
  • 小白也能懂的Qwen3-1.7B入门:零基础调用大模型教程
  • 显存占用过高?麦橘超然float8量化技术优化实战案例
  • 想试Flux又怕显存不够?麦橘超然帮你搞定
  • TurboDiffusion采样模式对比:ODE与SDE生成结果差异实测
  • 640×640适合通用场景,速度快内存占用低
  • 从0到1!小白也能玩转GPT-OSS开源模型
  • 【柔性板通过重构实现减阻】基于经验阻力公式的柔性板简化模型,研究了引发重构的两大机制——面积缩减与流线化(Matlab代码实现)
  • Python代码执行测试:gpt-oss-20b-WEBUI有多准确
  • 【灵敏度分析】一个肿瘤生长模型的伴随灵敏度分析及其在时空放射治疗优化中的应用(Matlab代码实现)
  • 手把手教程:调试LCD1602并口数据传输异常
  • 想微调自己的数据?cv_resnet18_ocr-detection训练功能详解
  • Qwen3-Embedding-0.6B部署实战:基于CSDN GPU Pod的全流程操作
  • 从零实现电机控制器的辅助电源设计
  • Qwen-Image-Edit-2511字体样式推断准,排版自动匹配风格
  • 中小企业如何低成本部署ASR?Paraformer镜像一键启动方案
  • GPT-OSS-20B开源价值:可定制化部署实战分析
  • 小白必看:一键启动麦橘超然,快速搭建本地AI画廊
  • 校园霸凌预防:教室录音中哭泣声自动报警系统