首页/新闻资讯/正文详情

彻底吃透 SSE 服务端推送:从原理到 SpringBoot 实战(替代 WebSocket 最简方案)

发布时间:2026/9/26 6:19:33 来源:云帆数科 栏目:资讯中心
彻底吃透 SSE 服务端推送:从原理到 SpringBoot 实战(替代 WebSocket 最简方案)
前言做过后端开发都知道前端想要实时拿服务端数据最常见两种方案前端轮询每秒请求一次接口—— 浪费服务器资源、延迟高WebSocket 双向长连接 —— 重、复杂、需要握手、需要心跳、断开重连麻烦但90% 的单向实时场景AI 流式输出、日志推送、消息通知、进度条、直播弹幕根本不需要 WebSocket这里就引出一个超级轻量、零配置、原生支持、专门服务端向客户端单向推送的技术SSEServer-Sent Events服务端推送事件本文从零手写彻底吃透 SSE 是什么、和 WebSocket 区别、适用场景、底层原理、SpringBoot 完整实战、多用户推送、异常重连、429 限流问题、AI 流式输出实战。一、什么是 SSE1.1 定义SSE 是一种基于 HTTP 协议的服务端单向推送技术。客户端发起一次 HTTP 请求服务端持续推送数据连接不断开直到客户端主动关闭。1.2 一句话区分轮询前端不断问后端 → 浪费请求WebSocket双向互通聊天、弹幕、游戏→ 太重SSE后端主动推给前端单向→ 最轻量二、SSE 核心优势优势 1基于原生 HTTP零配置不用握手、不用协议升级、不用心跳、不用处理帧格式。优势 2自带自动重连连接断开浏览器自动重试连接不用前端写重连逻辑。优势 3协议极简格式固定服务端只需要输出data: 内容\n\n优势 4天生支持流式输出AI 问答、代码生成、文本续写全部首选 SSE不用 WebSocket。优势 5资源极低、不占端口、性能极高三、SSE VS WebSocket3.1 适用场景完全不同SSE 适用单向推送AI 流式对话系统日志实时推送任务进度条消息通知服务端实时监控数据WebSocket 适用双向交互在线聊天实时游戏直播间互动协同编辑3.2 核心区别表协议通信方向重连机制数据格式复杂度SSEHTTP服务端 → 客户端单向浏览器自带自动重连纯文本极简WebSocketWS 自定义协议双向互通前端手动写重连二进制 / 文本复杂心跳、断连、帧解析、缓冲区四、SSE 底层协议规范SSE 响应头固定Content-Type: text/event-stream Cache-Control: no-cache Connection: keep-aliveSSE 固定报文格式data: 消息内容 event: 自定义事件名 id: 消息ID retry: 重连时间每条消息必须以 \n\n 结尾五、SpringBoot 完整 SSE 实战我们实现单用户实时推送多用户在线广播连接管理、断线释放模拟 AI 流式输出5.1 核心工具类 SSEConnectionManager用于保存、管理、释放所有客户端连接import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * SSE 连接管理器 * 支持多用户在线、广播、单点推送 */ public class SseConnectionManager { // 保存所有客户端连接 private static final MapString, SseEmitter CLIENT_MAP new ConcurrentHashMap(); // 建立连接 public static SseEmitter connect(String userId) { SseEmitter sseEmitter new SseEmitter(0L); // 永不超时 CLIENT_MAP.put(userId, sseEmitter); // 连接关闭回调 sseEmitter.onCompletion(() - CLIENT_MAP.remove(userId)); // 超时回调 sseEmitter.onTimeout(() - CLIENT_MAP.remove(userId)); // 异常回调 sseEmitter.onError(e - CLIENT_MAP.remove(userId)); return sseEmitter; } // 单点推送 public static void sendMsg(String userId, String msg) { try { SseEmitter emitter CLIENT_MAP.get(userId); if (emitter ! null) { emitter.send(msg); } } catch (Exception e) { CLIENT_MAP.remove(userId); } } // 全员广播 public static void broadcast(String msg) { CLIENT_MAP.forEach((k, v) - { try { v.send(msg); } catch (Exception e) { CLIENT_MAP.remove(k); } }); } // 关闭连接 public static void close(String userId) { CLIENT_MAP.remove(userId); } }5.2 编写 SSE 控制器import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; RestController RequestMapping(/sse) public class SseController { /** * 建立SSE长连接 */ GetMapping(/connect/{userId}) public SseEmitter connect(PathVariable String userId) { return SseConnectionManager.connect(userId); } /** * 单点推送消息 */ GetMapping(/send/{userId}/{msg}) public String send(PathVariable String userId, PathVariable String msg) { SseConnectionManager.sendMsg(userId, msg); return 推送成功; } /** * 全员广播 */ GetMapping(/broadcast/{msg}) public String broadcast(PathVariable String msg) { SseConnectionManager.broadcast(msg); return 广播成功; } /** * 关闭连接 */ GetMapping(/close/{userId}) public String close(PathVariable String userId) { SseConnectionManager.close(userId); return 关闭成功; } }六、SSE 常见坑坑 1SSE 超时断开解决new SseEmitter (0L) 设置永不超时坑 2连接堆积、内存泄漏解决必须 onCompletion /onTimeout/onError 清除连接坑 3Nginx 默认 60 秒断开生产 Nginx 必须配置proxy_read_timeout 3600s; proxy_send_timeout 3600s;坑 4429 太多请求报错前端不要疯狂重连可加间隔防抖。七、SSE 最佳业务场景总结AI 流式问答后台任务进度推送文件导入、导出、解压系统实时日志输出简单消息通知服务端监控实时数据推送只要不是双向聊天一律优先 SSE不用 WebSocket结语人生如棋世事若水弃子攻杀谷底待发落子无悔过眼云烟。人生线人生如棋弃子攻杀落子无悔。态度线世事若水谷底待发过眼云烟。up自己瞎写的加油陌生人

相关推荐

CLI-Anything:面向开发者的命令行智能体运行时
CLI-Anything:面向开发者的命令行智能体运行时

1. CLI-Anything 是什么:一个被严重低估的命令行智能体基建层你有没有过这种体验:在终端里敲下git commit -m "fix bug",心里却想着“要是能自动补全提交信息、检查是否漏了测试、顺手推到远程分支就好了”;或者写完一段… · 2026/9/26 6:19:33

SolidWorks 19-20安装排坑指南:环境兼容性与许可服务深度解析
SolidWorks 19-20安装排坑指南:环境兼容性与许可服务深度解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 6:19:33

金融系统核心架构设计:从幂等账务到合规风控的工程实践
金融系统核心架构设计:从幂等账务到合规风控的工程实践

两年前我接手一个支付系统重构,团队给我列的第一份材料不是架构图,也不是API文档,而是过去一年的故障复盘记录。那一刻我就明白了,financial-services这行和普通互联网业务有个本质区别:很多东西你没踩过坑&#xff0c… · 2026/9/26 6:19:33

NiubiGEO D/K协议实现分析:开源GEO测量引擎的Prompt与解析设计
NiubiGEO D/K协议实现分析:开源GEO测量引擎的Prompt与解析设计

NiubiGEO D/K协议实现分析:开源GEO测量引擎的Prompt与解析设计 【免费下载链接】niubigeo Open-source AI brand visibility and competitor reports. Official website: https://niubigeo.ai/ | Paid services: AI testing by real people and GEO optimization. P… · 2026/9/26 7:26:16

【AI】Codex 执行完成后自动发送飞书通知:TaoToken 统一 Key 配置与 Hook 验证
【AI】Codex 执行完成后自动发送飞书通知:TaoToken 统一 Key 配置与 Hook 验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 7:26:16

Java代码热更新全解析:原理、实战与踩坑指南
Java代码热更新全解析:原理、实战与踩坑指南

1. 热更新解决的痛点:从“改一行重启三分钟”说起代码热更新这件事,我最早被它“救命”是在做 Java Web 维护的时候。线上一个老项目出了个小 bug,按传统流程走:改代码、打包、传包、重启容器,前后折腾十几分钟&#x… · 2026/9/26 7:26:10

Zotero翻译插件选型与配置指南:从划词翻译到DeepSeek大模型接入
Zotero翻译插件选型与配置指南:从划词翻译到DeepSeek大模型接入

1. 学术文献阅读的痛点与Zotero翻译方案选型1.1 为什么我们需要在Zotero里直接翻译PDF读外文文献这件事,最折磨人的从来不是看不懂单词,而是在阅读器和翻译工具之间反复横跳。我早期读英文论文的流程是这样的:Zotero里打开PDF,遇到… · 2026/9/26 7:26:10

Thread Dump 实战:从 jstack 抓取到锁分析,快速定位 Java 线上性能问题
Thread Dump 实战:从 jstack 抓取到锁分析,快速定位 Java 线上性能问题

简介:这是一款面向Java开发者和运维人员的线程转储分析工具,主要用于诊断应用响应慢、无响应等并发问题,通过Web界面上传并解析线程转储文件,快速识别死锁、线程阻塞及堆栈异常。压缩包内含81个文件,包体仅1.49MB&… · 2026/9/26 7:26:10

APM 版本与锁文件深度解析:apm.lock.yaml 如何让 100 名开发者拿到字节级一致的 AI 智能体上下文
APM 版本与锁文件深度解析:apm.lock.yaml 如何让 100 名开发者拿到字节级一致的 AI 智能体上下文

APM 版本与锁文件深度解析:apm.lock.yaml 如何让 100 名开发者拿到字节级一致的 AI 智能体上下文 【免费下载链接】apm Agent Package Manager 项目地址: https://gitcode.com/gh_mirrors/apm10/apm APM(Agent Package Manager)是 AI … · 2026/9/26 7:26:10

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码