Server-Sent Events (SSE)

Server-Sent Events

  • Spring Boot 中使用 SSE
  • 原理

有一个需求,这个需求希望如果用户触发了下单操作,就对b端的管理员发送一次弹窗,如果想让前端源源不断的接受到后端发送的实时数据,这种需求可以使用什么技术来实现

可以采用以下几种技术方案:

1,WebSocket:WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,它允许网页和后端进行双端通信
2,Server-Sent Events (SSE):SSE 是一种让服务器向浏览器推送更新的技术。它基于 HTTP 协议,只需要服务器端发送一个特殊的 HTTP 响应头即可建立连接。与 WebSocket 相比,SSE 更加简单易用,但只能从服务器向客户端发送数据(单向通信)
3,轮询 (Polling):传统的轮询方式是指客户端定期向服务器发送请求以检查是否有新数据。这种方式实现起来比较简单,但是效率较低,尤其是在数据更新不频繁的情况下,会造成不必要的网络流量消耗

这里的 SSE 就是本文主要介绍的技术

Spring Boot 中使用 SSE

Server-Sent Events (SSE) 是HTML5引入的一种轻量级的服务器向浏览器客户端单向推送实时数据的技术。在 Spring Boot 框架中,我们可以很容易地集成并利用 SSE 来实现实时通信

        <!-- 集成beetl --><dependency><groupId>com.ibeetl</groupId><artifactId>beetl-framework-starter</artifactId><version>1.2.30.RELEASE</version></dependency><!-- 集成hutool工具类简便操作 --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.3.10</version></dependency>

核心的 SSE Client 代码

@Slf4j
@Component
public class SseClient {private static final Map<String, SseEmitter> sseEmitterMap = new ConcurrentHashMap<>();/*** 创建连接*/public SseEmitter createSse(String uid) {//默认30秒超时,设置为0L则永不超时SseEmitter sseEmitter = new SseEmitter(0l);//完成后回调sseEmitter.onCompletion(() -> {log.info("[{}]结束连接...................", uid);sseEmitterMap.remove(uid);});//超时回调sseEmitter.onTimeout(() -> {log.info("[{}]连接超时...................", uid);});//异常回调sseEmitter.onError(throwable -> {try {log.info("[{}]连接异常,{}", uid, throwable.toString());sseEmitter.send(SseEmitter.event().id(uid).name("发生异常!").data("发生异常请重试!").reconnectTime(3000));sseEmitterMap.put(uid, sseEmitter);} catch (IOException e) {e.printStackTrace();}});try {sseEmitter.send(SseEmitter.event().reconnectTime(5000));} catch (IOException e) {e.printStackTrace();}sseEmitterMap.put(uid, sseEmitter);log.info("[{}]创建sse连接成功!", uid);return sseEmitter;}/*** 给指定用户发送消息**/public boolean sendMessage(String uid,String messageId, String message) {if (StrUtil.isBlank(message)) {log.info("参数异常,msg为null", uid);return false;}SseEmitter sseEmitter = sseEmitterMap.get(uid);if (sseEmitter == null) {log.info("消息推送失败uid:[{}],没有创建连接,请重试。", uid);return false;}try {sseEmitter.send(SseEmitter.event().id(messageId).reconnectTime(1*60*1000L).data(message));log.info("用户{},消息id:{},推送成功:{}", uid,messageId, message);return true;}catch (Exception e) {sseEmitterMap.remove(uid);log.info("用户{},消息id:{},推送异常:{}", uid,messageId, e.getMessage());sseEmitter.complete();return false;}}/*** 断开* @param uid*/public void closeSse(String uid){if (sseEmitterMap.containsKey(uid)) {SseEmitter sseEmitter = sseEmitterMap.get(uid);sseEmitter.complete();sseEmitterMap.remove(uid);}else {log.info("用户{} 连接已关闭",uid);}}}

这里可以看到在业务端需要维护用户 id 和 SSE Client 的对应关系

当客户端断开连接时,SseEmitter 会抛出 IOException,所以务必捕获并处理这种异常,通常情况下我们会调用 emitter.complete 或 emitter.completeWithError 来关闭 SseEmitter

SSE 连接是持久性的,长时间保持连接可能需要处理超时和重连问题

原理

SSE 的底层原理相对简单,主要基于 HTTP 协议,并且遵循以下几个关键点:

1,HTTP 长连接:SSE 使用标准的 HTTP 请求来建立连接。客户端(通常是浏览器)通过发送一个带有 Accept 头的 GET 请求来请求一个 SSE 连接。服务器响应这个请求并保持连接打开,以便后续发送数据
2,MIME 类型:服务器在响应中返回一个 MIME 类型为 text/event-stream 的内容。这种 MIME 类型告诉客户端这是一个 SSE 连接,客户端会解析并处理这些数据
3,数据格式:SSE 数据以简单的文本格式发送,每条消息由一个或多个字段组成。常见的字段包括:

  • data: 消息的主要内容。
  • event: 指定事件类型,默认为 message。
  • id: 为每个事件分配一个唯一标识符,用于重新连接时恢复状态
  • retry: 指定在连接断开后重新连接的等待时间(以毫秒为单位)
  • 重连机制:如果连接中断,客户端会自动尝试重新连接。重连的时间间隔可以通过 retry 字段来控制。如果指定了 id 字段,服务器可以使用这个标识符来恢复之前的状态

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

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

相关文章

数据分区(Data Partitioning)

数据分区&#xff08;Data Partitioning&#xff09; 数据分区是指将一个大规模的数据集按某种规则划分成多个子集&#xff0c;并将这些子集存储到不同的存储节点上。这种方式不仅能提高查询效率&#xff0c;还能减轻单一节点的负担&#xff0c;使系统更容易扩展。 数据分区的…

Java | Leetcode Java题解之第486题预测赢家

题目&#xff1a; 题解&#xff1a; class Solution {public boolean PredictTheWinner(int[] nums) {int length nums.length;int[] dp new int[length];for (int i 0; i < length; i) {dp[i] nums[i];}for (int i length - 2; i > 0; i--) {for (int j i 1; j …

计算机毕业设计Python动漫视频分析可视化 动漫影视可视化 动漫情感分析 动漫爬虫 机器学习 深度学习 Tensorflow PyTorch LSTM模型

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系名片 &#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系名片 &#xff01; 温馨提示&#xff1a;文末有SDN 平台官方提供的学长联系名片 &#xff01; 基于Python的B站排行榜大数据分析与可视化系统…

【微信小程序_15_下拉刷新与上拉触底】

摘要:本文介绍了微信小程序的两种页面事件 —— 下拉刷新事件和上拉触底事件,具体内容如下: (1)下拉刷新事件 概念:通过手指下拉屏幕重新加载页面数据。 启用方式:包括全局和局部开启,推荐局部开启。 配置样式:可通过backgroundColor和backgroundTextStyle配置下拉刷新…

参加CSP-J/S 认证,要学多久C++才能达到获奖水平?

CSP-J/S 2024 第一轮认证报名阶段&#xff0c;认证将于9月21日举行。从去年CSP-J/S 认证报名人数近15万人来看&#xff0c;今年的报名人数也不会少&#xff0c;那么&#xff0c;对于基础的学子来说&#xff0c;如果参加CSP-J/S 认证&#xff0c;要学多久C才能达到获奖水平&…

最短路问题之dijikstra算法

//根据bfs修改而来 #include<stdio.h> #include<stdlib.h> typedef struct queue {int data;struct queue* next; }queue, * linklist; float dist_list[9]; //出发点为0 int forward_point_list[9] { -1 }; linklist front NULL; linklist rear NULL; float ma…

计算机的错误计算(一百二十五)

摘要 探讨算式 的计算精度问题。 例1. 已知 计算 不妨在 Excel 的单元格中计算&#xff0c;则有&#xff1a; 若在 Python 中计算&#xff0c;则似乎有更为精确的结果&#xff1a; 然而&#xff0c;16位的正确值是 0.3499999999999998e1&#xff08;ISRealsoft 提供&a…

RK3568笔记六十七:Live555拉流显示

若该文为原创文章转载请注明原文出处。 在项目中用到的功能是RTSP客户端,使用onvif获取RTSP地址,后通过live555解析视频流并在LCD显示。 这里记录使用live555拉取RTSP数据,解析视频流,并通过LCD显示。验证功能的可行性。 拉取RTSP使用的是live555的testRTSPClient.cpp程…

业务连续性管理(Business Continuity Management, BCM)

业务连续性管理&#xff08;Business Continuity Management, BCM&#xff09;是一种系统化的管理过程&#xff0c;旨在确保组织在面对各种潜在的灾难或中断事件时&#xff0c;能够继续提供关键产品和服务。BCM的目标是减少停机时间和恢复时间&#xff0c;最小化对客户、员工和…

前后端请求一致性学习

在进行前后端分离开发项目的过程中&#xff0c;前后端同学往往需要依照接口文档的基本信息以及相应的响应格式进行接口请求的开发&#xff0c;在这个过程中涉及到常见的Get、Post、Put、Patch等等的请求&#xff0c;相应的前后端的书写格式是什么&#xff0c;这篇文章进行一个记…

数据链中常见电磁干扰matlab仿真,对比噪声调频,线性调频,噪声,扫频,灵巧五种干扰模型

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 噪声调频干扰 4.2 线性调频干扰 4.3 噪声干扰 4.4 扫频干扰 4.5 灵巧干扰 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2022a 3…

Go语言中的时间比较与时区处理

文章目录 问题背景问题分析验证时区问题 解决方案方法 1&#xff1a;使用本地时区解析时间方法 2&#xff1a;将 time.Now() 转换为 UTC 最终结果总结 在后端开发中&#xff0c;时间处理往往是不可避免的&#xff0c;尤其是涉及到跨时区的应用时&#xff0c;时区问题常常会引发…

【黑马redis高级篇】持久化

//来源[01,05]分布式缓存 除了黑马&#xff0c;还参考了别的。 目录 1.单点redis问题及解决方案2.为什么需要持久化&#xff1f;3.Redis持久化有哪些方式呢&#xff1f;为什么我们需要重点学RDB和AOF&#xff1f;4.RDB4.1 定义4.2 触发方式4.2.1手动触发save4.2.2被动触发bgsa…

开源项目 - yolo v5 物体检测 手检测 深度学习

开源项目 - yolo v5 物体检测 手检测 深度学习 开源项目地址&#xff1a;https://gitcode.net/EricLee/yolo_v5 ​​ 助力快速掌握数据集的信息和使用方式。 数据可以如此美好&#xff01;

数据结构 ——— 顺序表oj题:验证回文串

目录 题目要求 代码实现 题目要求 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s&#xff0c;如果它是 回文串 &#xf…

JavaSE——集合4:List接口实现类—LinkedList

目录 一、LinkedList的全面说明 二、LinkedList的底层操作机制 (一)LinkedList添加结点源码 (二)LinkedList删除结点源码 三、LinkedList常用方法 四、ArrayList与LinkedList的选择 一、LinkedList的全面说明 LinkedList底层实现了双向链表和双端队列的特点可以添加任意…

Python安装|PyCharm Professional 下载安装教程。2024最新版,亲测使用!

一、下载地址&#xff1a; 二、Python的下载及安装&#xff1a; 1、从上面网址进入Python官网 2、安装流程图&#xff1a; 双击已经下载好的python-*.*.*-amd64.exe文件&#xff0c;开始安装 最后就等它自己安装完成就好了 3、检验是否安装完成&#xff1a; windowsR快捷键…

Vue 3 和 Vue Router 使用 createWebHistory 配置

在 Vue 3 项目中&#xff0c;如果使用 Vue Router 并希望启用 HTML5 History 模式&#xff0c;需要在创建路由器实例时传入 createWebHistory 作为历史模式的配置。此外&#xff0c;还需要确保在生产环境中设置正确的基本路径&#xff08;base&#xff09;&#xff0c;这样才能…

使用SSH进行GitHub的推送

使用SSH进行GitHub的推送是一种安全且便捷的方法。 以下是详细的步骤&#xff0c;配置SSH并通过SSH推送到GitHub&#xff1a; 对于同一个电脑&#xff0c;已经配置过的可以直接从步骤五开始 步骤一&#xff1a;检查是否已有SSH密钥 首先&#xff0c;检查计算机上是否已经有S…

权限修饰符

什么是权限修饰符&#xff1f; 就是用来限制类中的成员(成员变量、成员方法、构造器、代码块...)能够被访问的范围。 权限修饰符有几种&#xff1f;各自的作用是什么? 修饰符在本类中同一个包下的其他类里任意包下的子类里任意包下的任意类型 private √ 缺省…