网易首页 > 网易号 > 正文 申请入驻

2017 年后,SSE 已成为「单向实时推送」场景的主流方案之一

0
分享至

SSE 协议的核心规范在 2011 年完成 W3C 标准化,成为可商用的技术方案;

2021 年完成 IETF 层面的 HTTP 协议标准化

[笑哭]不是WebSocket不好,只是 SSE更有性价比

SSE 真正在行业内普及、成为消息推送主流方案之一的时间是 2015-2017 年

核心原因:

  1. 浏览器兼容性成熟:2015 年前后,IE 以外的主流浏览器(Chrome、Firefox、Safari、Edge)均已全面支持 EventSource API,解决了兼容性痛点;
  2. 业务场景适配需求:移动互联网爆发期,「服务端单向推送」场景(如订单通知、系统告警、实时日志)大量出现,sse 相比 WebSocket 更轻量(无需处理双向通信、无需额外协议升级),开发和运维成本更低,成为这类场景的首选;
  3. 框架生态支持:2015-2017 年,SpringBoot(2014 年发布)、Node.js 等主流后端框架完善了对 SSE 的原生支持(如 SpringBoot 的 SseEmitter 组件),降低了开发门槛;
  4. 对比 WebSocket 的差异化优势:WebSocket 虽适合双向通信,但部署成本高(需反向代理适配、长连接管理复杂),而 SSE 基于 HTTP,可直接复用现有 HTTP 基础设施(Nginx、CDN),中小团队更倾向用 SSE 实现单向推送。

SSE 协议的核心特性(本质属性)1. 基于 HTTP/1.1 协议,无需额外升级

  • SSE 完全复用 HTTP 协议栈,客户端通过普通 GET 请求建立连接,服务端返回 Content-Type: text/event-stream 响应即可,无需像 WebSocket 那样经历「HTTP 升级为 WebSocket 协议」的握手过程;
  • 可直接复用现有 HTTP 基础设施(Nginx、CDN、负载均衡),无需额外配置,部署成本极低。
2. 单向通信:仅服务端向客户端推送
  • 核心定位是「服务器→客户端」的单向数据传输,客户端无法通过 SSE 连接向服务端发送数据(若需客户端交互,需配合普通 HTTP/POST 请求);
  • 完美适配「通知推送、实时日志、状态更新」等单向场景,避免了 WebSocket 双向通信的冗余设计。
3. 文本流传输,格式标准化
  • 服务端推送的数据是结构化的文本流(而非二进制),遵循固定格式(event:/data:/id:/retry: 字段 + 空行结束);
  • 浏览器原生 EventSource API 可自动解析格式,无需前端手动处理流数据,开发成本低。





4. 内置自动重连机制

  • 浏览器的 EventSource 会在连接断开(如网络异常、服务端重启)时自动重试,默认重连间隔 3 秒;
  • 服务端可通过 retry: 字段自定义重连间隔(如 retry: 5000 表示 5 秒重试),客户端也可通过 lastEventId 记录最后接收的消息 ID,实现消息续传。
5. 长连接 + 分块传输
  • 基于 HTTP 长连接实现,连接建立后保持打开状态,服务端可随时推送数据;
  • 服务端采用「分块传输编码(Transfer-Encoding: chunked)」,数据分批次发送,无需等待完整响应,实时性接近 WebSocket。、







html>charset="UTF-8">SSE 实时消息推送测试
SpringBoot SSE 实时消息推送测试


用户ID: 建立连接 断开连接

消息内容: 推送给当前用户 广播给所有用户 查看在线数




package com.example.sse.manager;* @author* @title: SseEmitterManager* @description: TODOimport lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Component;import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;import java.io.IOException;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.atomic.AtomicInteger;* SSE连接管理器:维护用户与SSE连接的映射,处理连接生命周期@Slf4j@Componentpublic class SseEmitterManager {// 线程安全的Map,存储用户ID -> SSE连接private final Map sseEmitterMap = new ConcurrentHashMap<>();// SSE连接超时时间:30分钟(1800000毫秒),可根据业务调整private static final long TIMEOUT = 1800000L;// 统计当前在线连接数private final AtomicInteger onlineCount = new AtomicInteger(0);* 创建并保存用户的SSE连接* @param userId 用户唯一标识* @return SseEmitter 连接对象public SseEmitter createSseEmitter(String userId) {// 创建SSE发射器,设置超时时间SseEmitter emitter = new SseEmitter(TIMEOUT);// 保存连接到MapsseEmitterMap.put(userId, emitter);onlineCount.incrementAndGet();log.info("用户[{}]建立SSE连接,当前在线数:{}", userId, onlineCount.get());// 连接超时回调:移除无效连接emitter.onTimeout(() -> {log.warn("用户[{}]的SSE连接超时", userId);removeEmitter(userId);// 连接完成回调(客户端主动断开)emitter.onCompletion(() -> {log.info("用户[{}]的SSE连接已完成", userId);removeEmitter(userId);// 连接异常回调emitter.onError(e -> {log.error("用户[{}]的SSE连接异常", userId, e);removeEmitter(userId);return emitter;* 向指定用户推送消息* @param userId  用户ID* @param message 消息内容(支持字符串/JSON)public void sendToUser(String userId, String message) {if (!sseEmitterMap.containsKey(userId)) {log.warn("用户[{}]未建立SSE连接,推送失败", userId);return;SseEmitter emitter = sseEmitterMap.get(userId);try {// 发送消息:指定事件ID、事件类型、消息内容emitter.send(SseEmitter.event().id(String.valueOf(System.currentTimeMillis()))  // 消息唯一ID.name("custom-message")                         // 自定义事件类型(前端可根据此过滤).data(message));                                // 消息内容log.info("向用户[{}]推送消息:{}", userId, message);} catch (IOException e) {log.error("向用户[{}]推送消息失败", userId, e);removeEmitter(userId); // 推送失败,移除无效连接* 广播消息:推送给所有在线用户* @param message 广播内容public void broadcast(String message) {if (sseEmitterMap.isEmpty()) {log.warn("无在线用户,广播消息失败:{}", message);return;sseEmitterMap.forEach((userId, emitter) -> {try {emitter.send(SseEmitter.event().id(String.valueOf(System.currentTimeMillis())).name("broadcast-message").data(message));} catch (IOException e) {log.error("向用户[{}]广播消息失败", userId, e);removeEmitter(userId);log.info("广播消息完成,覆盖{}个在线用户,消息内容:{}", onlineCount.get(), message);* 移除用户的SSE连接(释放资源)* @param userId 用户IDpublic void removeEmitter(String userId) {if (sseEmitterMap.containsKey(userId)) {SseEmitter emitter = sseEmitterMap.remove(userId);if (emitter != null) {emitter.complete(); // 主动完成连接,释放资源onlineCount.decrementAndGet();log.info("用户[{}]的SSE连接已移除,当前在线数:{}", userId, onlineCount.get());* 获取当前在线用户数* @return 在线数public int getOnlineCount() {return onlineCount.get();

推送给具体某个用户



广播给所有用户



想要获取完整代码的小伙伴看过来啦!

不管是评论区留言,

还是私信我都可以,

看到后会第一时间发你哦✨

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
中国小伙在澳失联最新!遗体已找到,只剩下头颅,警方定性引争议

中国小伙在澳失联最新!遗体已找到,只剩下头颅,警方定性引争议

李健政观察
2026-01-09 12:08:28
中国通告全球对日下禁令,日本威胁反击,高市早苗手上仅剩一张牌

中国通告全球对日下禁令,日本威胁反击,高市早苗手上仅剩一张牌

博览历史
2026-01-09 18:05:34
泽连斯基引发的链式反应:叙利亚、哈马斯、黎巴嫩真主党、委内瑞拉、伊朗

泽连斯基引发的链式反应:叙利亚、哈马斯、黎巴嫩真主党、委内瑞拉、伊朗

高博新视野
2026-01-08 20:22:29
我妈被姑姑扇了4巴掌,我爸静了5秒,然后摘下45万手表递给我妈:媳妇,咱们这就离开这个家

我妈被姑姑扇了4巴掌,我爸静了5秒,然后摘下45万手表递给我妈:媳妇,咱们这就离开这个家

起飞做故事
2026-01-08 20:18:07
闹大了!闫学晶儿子是中戏新疆班,网友呼吁严查,这下她真要哭了

闹大了!闫学晶儿子是中戏新疆班,网友呼吁严查,这下她真要哭了

非常先生看娱乐
2026-01-09 17:10:34
北京输球揪出最大废才!拿600万半场1分,被人隔扣恼羞成怒+吃T

北京输球揪出最大废才!拿600万半场1分,被人隔扣恼羞成怒+吃T

南海浪花
2026-01-09 22:19:56
女单四强对阵:王曼昱VS韩莹,蒯曼VS长崎美柚,王艺迪困难

女单四强对阵:王曼昱VS韩莹,蒯曼VS长崎美柚,王艺迪困难

余憁搞笑段子
2026-01-10 02:25:19
朝鲜不会成为第二个委内瑞拉!因为朝鲜有两个后盾

朝鲜不会成为第二个委内瑞拉!因为朝鲜有两个后盾

米君文史
2026-01-07 10:01:47
神仙姐姐的野生图,太美了。

神仙姐姐的野生图,太美了。

微微热评
2026-01-09 12:20:53
伊朗步入十字路口:抗议者焚烧革命卫队总部!撕毁哈梅内伊肖像

伊朗步入十字路口:抗议者焚烧革命卫队总部!撕毁哈梅内伊肖像

项鹏飞
2026-01-09 19:37:50
李在明访华刚回国,就通告全球,与高市共进晚餐,3亿大单白签?

李在明访华刚回国,就通告全球,与高市共进晚餐,3亿大单白签?

南宫一二
2026-01-09 17:57:40
谢贤前女友大曝恋爱私隐!三年不碰她,却每天给她做“四哥菜芯”

谢贤前女友大曝恋爱私隐!三年不碰她,却每天给她做“四哥菜芯”

阿纂看事
2026-01-09 10:19:00
亚洲杯乱了:东南亚球队2连胜提前晋级,东道主爆冷输球后濒临出局

亚洲杯乱了:东南亚球队2连胜提前晋级,东道主爆冷输球后濒临出局

侧身凌空斩
2026-01-10 04:19:51
“让我睡一次,不然死给你看!”17岁少年持刀,威胁舅妈发生关系

“让我睡一次,不然死给你看!”17岁少年持刀,威胁舅妈发生关系

有书
2026-01-09 21:30:59
广湛高铁工地工人从桥面扔铁模板砸中一放牛老人致死,事故调查报告公布

广湛高铁工地工人从桥面扔铁模板砸中一放牛老人致死,事故调查报告公布

澎湃新闻
2026-01-09 18:42:27
乱套了!男单8强赛出炉,世界冠军2-3被淘汰,林昀儒下轮对阵确定

乱套了!男单8强赛出炉,世界冠军2-3被淘汰,林昀儒下轮对阵确定

卿子书
2026-01-09 08:44:25
冲突升级!美抓捕影子油轮与俄核潜艇大西洋对峙,强行登船扣船

冲突升级!美抓捕影子油轮与俄核潜艇大西洋对峙,强行登船扣船

史政先锋
2026-01-08 12:50:30
四强赛对阵:张本遇克星,林诗栋怼梁靖崑,小莫战张禹珍!

四强赛对阵:张本遇克星,林诗栋怼梁靖崑,小莫战张禹珍!

吕彍极限手工
2026-01-10 03:01:38
南通市第一人民医院就宋女士医疗事件致歉

南通市第一人民医院就宋女士医疗事件致歉

新京报
2026-01-09 20:24:35
这么冷,那么贵:河北农村的第八个寒冬

这么冷,那么贵:河北农村的第八个寒冬

水瓶纪元
2026-01-07 18:27:32
2026-01-10 06:00:49
娱乐督察中
娱乐督察中
独乐乐不如众乐乐
192文章数 20434关注度
往期回顾 全部

科技要闻

市场偏爱MiniMax:开盘涨42%,市值超700亿

头条要闻

媒体称委内瑞拉代总统计划13日访问华盛顿 委方回应

头条要闻

媒体称委内瑞拉代总统计划13日访问华盛顿 委方回应

体育要闻

金元时代最后的外援,来中国8年了

娱乐要闻

关晓彤鹿晗风波后露面 不受影响状态佳

财经要闻

投资必看!瑞银李萌给出3大核心配置建议

汽车要闻

助跑三年的奇瑞 接下来是加速还是起跳?

态度原创

房产
游戏
时尚
健康
本地

房产要闻

66万方!4755套!三亚巨量房源正疯狂砸出!

怎么会有游戏上来就说自己的新服活不过10天啊?"/> 主站 商城 论坛 自运营 登录 注册 怎么会有游戏上来就说自己的新服活不过10天啊? 廉颇 202...

推广中奖名单-更新至2025年12月19日推广

这些新疗法,让化疗不再那么痛苦

本地新闻

云游内蒙|“包”你再来?一座在硬核里酿出诗意的城

无障碍浏览 进入关怀版