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

Java Server-Sent Event 服务端发送事件

实现后端单方面向前端发消息

1·后端提供订阅接口
import lombok.extern.slf4j.Slf4j;
import service.ServerSentEventService;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;import javax.annotation.Resource;/*** 用于提醒前端刷新列表*/
@Slf4j
@RestController
public class ServerSentEventController {@Resourceprivate ServerSentEventService serverSentEventService;@GetMapping(path = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<String> streamEvents() {Flux<String> flux = serverSentEventService.getFlux();log.info("flux :{}",flux);return flux;}}
import org.springframework.stereotype.Service;import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Sinks;@Slf4j
@Service
public class ServerSentEventService {private Sinks.Many<String> sink = Sinks.many().multicast().onBackpressureBuffer();public Flux<String> getFlux() {Flux<String> flux = sink.asFlux().onErrorResume(e -> {log.info("SSE-Flux出错: " + e.getMessage());log.info("重新创建flux。");sink = Sinks.many().multicast().onBackpressureBuffer();return sink.asFlux();}).doOnTerminate(() -> {log.info("SSE-客户端断开连接");log.info("重新创建Sink。");sink = Sinks.many().multicast().onBackpressureBuffer();}).startWith("服务器收到订阅");return flux;}public void sendMessage(String message) {sink.tryEmitNext(message);}
}
2前端订阅接口
const connect = () => {// eventSource = new EventSource('http://localhost/stream');eventSource = new EventSource('/stream');eventSource.onmessage = event => {console.log(`收到服务端消息:${event.data}`);//在这里对消息作处理};
}const closeConnection = () => {if (eventSource) {console.log('尝试关闭连接');eventSource.close();console.log('连接状态'+eventSource.readyState);}
};
3·后端发消息
//注入服务端发送事件service   
@Resource
private ServerSentEventService serverSentEventService;//调用发消息方法serverSentEventService.sendMessage("%s_error_%s".formatted(requestUUID,"方案名不能为空。"));

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • [FSCTF 2023]细狗2.0
  • 力扣热题100_二叉树_94_二叉树的中序遍历
  • C语言中常用的函数
  • python自动化笔记:excel文件处理及日志收集
  • 列式数据库(HBase) 中实现表与表的关联
  • 区块链(Blockchain)
  • 【代码随想录】长度最小的子数组——滑动窗口
  • 第二十一节、敌人追击状态的转换
  • 【K8S】K8S架构及相关组件
  • PHP反序列化POP链构造:理解与利用
  • IT运维岗适用的6本证书
  • 如何在前后端分离项目中,使用Spring Security
  • 英特尔凌动® P5300 和 P5700 处理器使企业能够优化现代网络基础架构、安全加速器和存储设备之间的性能和成本平衡。
  • leetcode:1822. 数组元素积的符号(python3解法)
  • JMeter 性能测试工具入门与实践
  • Angular 4.x 动态创建组件
  • Docker 笔记(2):Dockerfile
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • JS笔记四:作用域、变量(函数)提升
  • JS基础之数据类型、对象、原型、原型链、继承
  • leetcode98. Validate Binary Search Tree
  • Logstash 参考指南(目录)
  • MQ框架的比较
  • Redash本地开发环境搭建
  • Vue.js 移动端适配之 vw 解决方案
  • 前端性能优化--懒加载和预加载
  • 十年未变!安全,谁之责?(下)
  • 双管齐下,VMware的容器新战略
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • 写给高年级小学生看的《Bash 指南》
  • 最简单的无缝轮播
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • # Redis 入门到精通(一)数据类型(4)
  • #includecmath
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • (4)事件处理——(7)简单事件(Simple events)
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (独孤九剑)--文件系统
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (附源码)ssm经济信息门户网站 毕业设计 141634
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • (转)IOS中获取各种文件的目录路径的方法
  • (自用)网络编程
  • .“空心村”成因分析及解决对策122344
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .NET DataGridView数据绑定说明
  • .net framework profiles /.net framework 配置
  • .Net IE10 _doPostBack 未定义
  • .Net Memory Profiler的使用举例