springboot使用SSE

2023-11-15

1、pom文件 

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

2、前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title> Springboot集成SSE </title>
</head>
<script>
    let source = null;
    const clientId = new Date().getTime();
    if (!!window.EventSource) {

        source = new EventSource('http://127.0.0.1:8080/sse/subscribe?id=' + clientId);

    	//建立连接
        source.onopen = function (event) {
            setMessageInnerHTML("建立连接" + event);
        }
        //接收数据
        source.onmessage = function (event) {
            setMessageInnerHTML(event.data);
        }
        //错误监听
        source.onerror = function (event) {
            if (event.readyState === EventSource.CLOSED) {
                setMessageInnerHTML("连接关闭");
            } else {
                console.log(event);
            }
        }
    } else {
        setMessageInnerHTML("浏览器不支持SSE");
    }

    window.onbeforeunload = function () {
        close();
    };

    // 关闭
    function close() {
        source.close();
        const httpRequest = new XMLHttpRequest();
        httpRequest.open('GET', '/sse/over/?clientId=' + clientId, true);
        httpRequest.send();
        console.log("close");
    }

    // 显示消息
    function setMessageInnerHTML(innerHTML) {
        document.getElementById('text').innerHTML += innerHTML + '<br/>';
    }
</script>
<body>
<button onclick="close()">关闭连接</button>
<div id="text"></div>
</body>
</html>

3、后端代码

1、订阅
private static Map<String, SseEmitter> cache = new ConcurrentHashMap<>();
	@GetMapping(path = "subscribe", produces = {MediaType.TEXT_EVENT_STREAM_VALUE})
	public SseEmitter subscribe(@RequestParam(name = "id", required = false) String id) throws IOException {
		// 超时时间设置
		SseEmitter sseEmitter = new SseEmitter(0L);
		
		cache.put(id, sseEmitter);
		//结束连接
		sseEmitter.onCompletion(() -> {
			log.info("结束连接:{}", id);
			cache.remove(id);
		});
		//连接异常
		sseEmitter.onError(throwable -> {
			log.info("连接异常:{}", id);
			cache.remove(id);
		});
		//连接超时
		sseEmitter.onTimeout(() -> {
			log.info("连接超时:{}", id);
			cache.remove(id);
		});
		return sseEmitter;
	}
2、推送
@GetMapping(path = "push/{userId}")
	public String push(@PathVariable String userId,@RequestBody Map<String,Object> param) throws IOException {
		try {
			SseEmitter sseEmitter = cache.get("123");
			if (sseEmitter != null) {
				sseEmitter.send(SseEmitter.event().name("msg").data("后端发送消息:" + param));
			}
		} catch (IOException e) {
			log.error("用户[{}]推送异常:{}", userId, e.getMessage());
			cache.remove(userId);
		}
		return "over";
	}
3、关闭
@GetMapping(path = "over")
	public String over(@RequestParam(name = "id", required = false) String id) {
		SseEmitter sseEmitter = cache.get(id);
		if (sseEmitter != null) {
			sseEmitter.complete();
			cache.remove(id);
		}
		return "over";
	}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

springboot使用SSE 的相关文章

随机推荐

  • 欧拉降幂(广义欧拉降幂)

    第一个要求a和p互质 第二个和第三个是广义欧拉降幂 不要求a和p互质 但要求b和的大小关系 A K A K m m mod m K gt m 1 证明如下 1 若 A m 1 根据欧拉定理 A m 1 mod m 即可轻易得证 2 若 A
  • Java基础之比较器

    文章目录 一 背景 二 Comparable 自然排序 三 Comparator 定制排序 一 背景 Java中的对象 正常情况下 只能进行比较 或 不能使用 gt 或 lt 的 但是在开发场景中 我们需要对多个对象进行排序 言外之意 就需
  • 斗地主练习(按照斗地主的规则,完成洗牌发牌的动作。)

    按照斗地主的规则 完成洗牌发牌的动作 具体规则 使用54张牌 打乱顺序 三个玩家参与游戏 三人交替摸牌 每人17张牌 最后三张留作底牌 手中的牌按从小到大的顺序排列 import java util ArrayList import jav
  • 记下对方的证据,抹掉自己的证据

    记下对方的证据 抹掉自己的证据 http blog vsharing com itdays A908824 html 原创 记下对方的证据 抹掉自己的证据 公司另一个部门让我告诉他们 我们的国外那家技术服务商的服务怎么样 正好被那家公司给折
  • 【有奖下载】IMG DXT GPU 让光线追踪触手可及

    继 IMG CXT GPU 之后 2023 年 1 月 Imagination 正式推出 IMG DXT GPU 这款开创性的光追 GPU 将为所有移动设备用户带来最先进的图形技术 从高端设备到主流设备 D 系列的首款产品 IMG DXT
  • this is biaoti

    富文本咯咯咯咯咯咯 早上好吃了吗
  • LVS/NAT双主 + keepalived负载均衡实现

    一 keepalived简介 keepalived是分布式部署解决系统高可用的软件 结合lvs LinuxVirtual Server 使用 解决单机宕机的问题 keepalived是一个基于VRRP协议来实现IPVS的高可用的解决方案 对
  • properties文件中用注释的方法

    很简单 用
  • DPDK-流分类与多队列

    1 前言 多队列与流分类技术基本被应用到所有DPDK网关类项目中 比如开源的DPVS 美团的四层网关等等 利用多队列及分流技术可以使得网卡更好地与多核处理器 多任务系统配合 从而达到更高效IO处理的目的 这章节以英特尔的网卡为例 介绍多队列
  • 百度翻译破解

    破解百度翻译 1 页面基本信息 打开对应页面 直接搜索 百度翻译 打开百度翻译如图 需求 获取某个单词或句子的翻译结果 键入要翻译的关键字后 页面局部刷新 依旧使用的是AJAX 2 数据抓包 进入XHP页面获取Ajax实际请求地址及相关参数
  • Sqli-labs靶场详细攻略Less 34-37

    Less 34 37 Less 34 POST Bypass AddSlashes 这一关还是进行宽字节注入 与上一关的区别在于使用了post方法进行传递 先试一下上一关的注入代码 因为这一关是登录 就使用之前的dumb账号 dumb df
  • onenote标注pdf笔记_使用OneNote做文献阅读笔记的正确打开方式

    又到了紧张赶毕业论文的时候了 写毕业论文的时候 文献阅读是一个必不可少的环节 但是 当需要阅读的文献越来越多 需要记录的阅读笔记也越来越多时 问题来了 有没有自动保存笔记的方法 文献阅读的笔记太多 如何快速找到想要的文献笔记 有没有方法可以
  • QGIS:生成网格的步骤

    第一步 打开工具箱中的 创建网格 第二步 按照自己的需求设置参数 特别说明 1 网格类型要选 矩形 默认是点 2 网格范围可以自己定义范围 右边倒三角点开第三个 3 间隔设置不能超过网格范围 单位跟选择的坐标参考系相关联 mercator坐
  • 贝叶斯优化 Bayesian Optimization

    贝叶斯优化算法 BOA 贝叶斯优化算法BOA 背景介绍 贝叶斯优化流程 形式化 算法流程 核心算法 Prior Function Acquisition Function 参考文献 背景介绍 当前的场景中 会面临很多设计选择问题 比如说在工
  • Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node ……

    解决办法是加一个等待时间即可解决问题 setTimeout function you code 5
  • 在一台电脑上用不同端口同步以太坊区块链节点

    首先要获取第一个节点的信息 在第一个节点的控制台中输入 gt admin nodeInfo enode 将输出的结果用鼠标操作复制 然后在第二个节点的JS控制台中添加第一个节点为静态节点 输入 gt admin addPeer 例如admi
  • AdminLTE3框架下的BootStrap Modal 模态框

    直接贴出栗子 里面有注解
  • 主机与VMware的Linux虚拟机之间共享交换文件

    搭建环境 主机系统 Windows7 Ultimate VM软件 VMware Workstation 7 1 3 虚拟机系统 Linux Ubuntu 10 10 操作步骤 1 在主机上新建一个共享路径 用于将来和虚拟机之间进行共享文件
  • 几种常见模式识别算法整理和总结

    这学期选了门模式识别的课 发现最常见的一种情况就是 书上写的老师ppt上写的都看不懂 然后绕了一大圈去自己查资料理解 回头看看发现 Ah ha 原来本质的原理那么简单 自己一开始只不过被那些看似formidable的细节吓到了 所以在这里把
  • springboot使用SSE

    1 pom文件