SseEmitter(SSE) vs WebSocket 核心区别
·
SseEmitter(SSE) vs WebSocket 核心区别
先理清基础概念:
- SSE(Server-Sent Events,服务器推送事件):基于HTTP的单向长连接;Spring 封装实现就是 SseEmitter
- WebSocket:独立协议(ws:/// wss://),双向全双工长连接
一、核心特性对比
表格
| 对比维度 | SSE(SseEmitter) | WebSocket |
|---|---|---|
| 通信方向 | 单向:服务器 → 客户端客户端只能发普通 HTTP 请求,不能在长连接通道内发消息 | 双向全双工客户端 ↔ 服务器随时互发消息 |
| 底层协议 | 标准 HTTP/1.1,响应头 Content-Type: text/event-stream | 独立协议 WebSocket(RFC6455),由 HTTP 握手升级而来 |
| 浏览器兼容性 | 现代浏览器全部支持;IE 不支持 | 几乎所有现代浏览器,兼容性更好 |
| 传输格式 | 文本为主,原生不支持二进制 | 文本 + 二进制数据都支持 |
| 断线重连 | 浏览器内置自动重连,自带Last-Event-ID断点续传 | 没有内置重连,需要前端手动实现重连逻辑 |
| 网络代理 / 防火墙 | 友好,走标准 HTTP 80/443 端口,极少被拦截 | 部分老旧防火墙会拦截非 HTTP 流量 |
| 最大并发开销 | HTTP 连接,受服务端 HTTP 连接池限制 | 连接更轻量,长连接无重复 HTTP 头开销 |
| Spring 实现 | SseEmitter(开箱即用) | 原生无封装,一般用 Spring WebSocket(WebSocketHandler) |
二、通信流程简单演示
1. SSE(SseEmitter)
- 前端发起一次 GET HTTP 请求
- 服务端不关闭响应流,持续不断向后推送事件
- ✅ 服务端发消息 → 前端接收
- ❌ 前端无法在这条长连接上直接发消息给后端
前端如果要向后端传数据,必须额外发起新的 ajax/fetch 请求
2. WebSocket
- 前端发起 HTTP 握手请求
- 服务端响应
101 Switching Protocols,协议升级为 ws - 通道永久打通:客户端、服务器随时互相发送消息
三、适用场景(重点,开发选型参考)
✅ 优先选 SseEmitter(SSE)
- 只需要服务器向客户端推送数据(监控面板、实时日志、进度推送、消息通知)
- 不想处理双向交互、追求简单开发
- 担心防火墙拦截,希望复用 HTTP 端口
- 需要自带断线自动重连
典型场景:文件导入进度条、实时大屏指标、系统站内通知
✅ 优先选 WebSocket
- 双向实时交互(聊天、协同编辑、游戏、实时答题)
- 需要传输二进制数据
- 客户端频繁向服务端发送实时指令
典型场景:在线聊天、物联网设备双向指令、实时对战
四、开发层面优缺点(Spring 环境)
SseEmitter
✅ 优点
- API 极简,Spring 直接提供,无需额外配置握手
- 浏览器自动重连,支持断点续传
- 基于 HTTP,nginx 反向代理配置简单
❌ 缺点
- 单向通信硬限制
- 默认只能传输文本
- 大量并发长连接时,Tomcat 等容器需调大
maxConnections
WebSocket
✅ 优点
- 双向通信,灵活性最高
- 二进制支持,头部开销小,高并发实时场景性能更好
❌ 缺点
- 需要自己处理断线重连、心跳保活(防止连接被代理断开)
- 前端、后端代码量更多
- 部分老旧网络环境更容易被拦截
五、高频误区澄清
-
误区:SseEmitter 是一套独立协议 纠正:SseEmitter 只是 Spring 对SSE 规范的封装,底层依然是 HTTP 长轮询变种。
-
误区:SSE 不能双向通信 纠正:通道内不能双向;想要双向只能「SSE 接收推送 + 额外 HTTP 接口上传指令」,属于折中方案。
-
误区:WebSocket 就是 HTTP 长连接 纠正:握手阶段用 HTTP,成功后切换成独立 ws 协议,不再遵循 HTTP 请求 - 响应模型。
六、最简选型口诀
单向推送用 SseEmitter,双向交互用 WebSocket
更多推荐




所有评论(0)