SseEmitter 完整讲解(Spring 专属,适配你 Java 电商后端)
一、基础定义
SseEmitter 是 Spring MVC 提供实现 SSE(Server-Sent Events)的原生工具类。
Java 后端想要做服务端流式推送,不用自己手写底层 HTTP 流,直接用 SseEmitter 封装。
本质:把普通 HTTP 响应包装成 SSE 长连接,后端可以分多次、间断向前端推送多条消息,连接不断开。
二、核心对应你的业务场景
你们想做的效果:
第一次推送:返回首屏 2~3 张商品卡极简数据(图片、标题),页面立刻渲染;
间隔一小段时间,后端跑完 mixer、商卡、pbjc 限购等复杂逻辑;
第二次推送完整全量卡片、所有补充字段;
使用 SseEmitter 只需要前端发 1 次请求建立连接,后端分批次 send 推送。完全替代现在「双请求 A+B+Redis 锁」的笨重方案。
三、极简工作流程
前端发起 GET 请求,接口返回 SseEmitter,HTTP 长连接建立;
后端拿到 SseEmitter 对象,调用send()向前端推送第一批首屏 2-3 卡基础数据;前端接收渲染页面;
后端异步线程继续调用 mixer、商卡服务、组装 pbjc 屏蔽加车字段;
组装完毕,再次调用send()推送剩余全部数据;
全部推送完成,执行complete()关闭连接;前端正常接收两段数据。
全程只有一次 HTTP 请求,不需要双请求、不需要 Redis 做跨请求传值、不需要分布式锁控顺序。
四、关键能力
天然适配 SSE 协议:自动按照 SSE 规范封装data、event、id 格式,前端 EventSource 可以直接解析;
支持异步:不会占用 Tomcat 核心工作线程,耗时逻辑丢进线程池;
自带回调:可以监听连接断开、异常、超时,用户关掉页面时后端能感知,及时停止查询下游接口,节约资源;
支持自定义事件名:可以区分推送类型,比如firstScreen首屏数据、fullData全量数据,前端按事件分别处理渲染。
五、和你现有双请求方案对比
表格
方案 依赖 Redis 请求次数 时序风险 维护复杂度
SseEmitter 标准 SSE 不需要 1 次 无,后端主动控制推送顺序 低,没有锁和缓存逻辑
双请求 A+B 必须要锁 + 缓存 2 次 网络乱序会流程错乱 高,需要维护锁、缓存读写、防重复
六、贴合你的商详业务举例伪代码逻辑
java
运行
// 接口返回SseEmitter
@GetMapping("/recommend/lookAgain")
public SseEmitter getRecommendData() {
SseEmitter emitter = new SseEmitter(30000L); // 超时30秒
// 异步执行业务
executor.execute(() -> {
// 第一批:首屏2~3卡极简数据
List<SimpleCard> firstCards = mixer.getFirstScreenCard();
emitter.send(SseEmitter.event().name("first").data(firstCards));
// 执行耗时补充逻辑:商卡、pbjc、全部商品
List<FullCard> fullList = buildFullData(firstCards);
emitter.send(SseEmitter.event().name("full").data(fullList));
emitter.complete();
});
return emitter;
}
前端用EventSource监听first事件先渲染首屏,监听full事件补全列表。
七、补充痛点
SSE 只能后端推前端,前端无法通过这条通道发消息;你的场景只需要后端推送,完全够用;
SseEmitter 长连接量大时需要调整容器线程、超时参数;
你们早期没有统一封装 SseEmitter 工具类,才被迫用双请求 + Redis 临时兜底。