我之前有个疑问SSE是前端给后端发消息,后端给前端推送,Webscoket不是这样吗,还有sse那种流式推送和后端return的区别。
下面是总结:
长轮询、SSE、WebSocket 完整总结
底层都是 TCP 网络,只是上层应用协议、连接模型不一样
1. 长轮询
- 协议:纯 HTTP 短连接,没有协议升级,每次都是完整 http 请求响应
- 流程:前端发 http 请求,后端先把请求挂住不返回;等到有新数据才响应回来。前端收到响应,立刻再发起下一个新 http 请求。
- 流向:双向,前端可以传参数,后端返回数据
- 缺点:每一次数据交互都要完整 HTTP 报文,有请求头、重复建立连接开销,性能一般
- 使用场景:老旧浏览器兼容兜底,现在新项目很少优先用
本质就是不停循环发普通 http 请求。
2.SSE(服务器推送事件,AI 流式打字就是它)
- 协议:HTTP 长连接,不改变 HTTP 协议 ,响应头固定
Content‑Type: text/event‑stream - 流程:前端只发起一次 http 请求,连接保持不断开。后端可以持续分段把碎片数据源源不断推给前端,一边生成一边发送,页面就是打字效果。
- 流向:单向!只允许后端 → 前端推送消息 ⚠️重点:这条 SSE 长连接管道前端不能发数据给后端 。 如果前端要给后端发指令(点击按钮、发送提问),必须额外调用普通
@PostMapping/@GetMappingHTTP 接口。 - 特点:浏览器自带断线自动重连;只支持文本数据
- 适用场景:大屏监控、日志输出、AI 流式回答;只后端推送,前端很少上报数据
3.WebSocket
- 协议:握手阶段是 HTTP ,请求头携带
Upgrade:websocket,后端返回101 Switching Protocols,完成协议升级。 握手成功之后,TCP 连接保留,不再走 HTTP 协议,切换成 ws 协议。 - 流程:建立一条持久双向 TCP 通道。 前端调用
ws.send()发送消息,不会访问 Controller 的 HTTP 接口 ;消息以 ws 协议帧直接走已有的长连接传给后端。 后端通过@OnMessage回调函数接收消息;后端也可以用 session 直接向前端推送消息。 - 流向:真正双向,同一条长连接,前后端都可以随时发送消息。后端也可以写定时任务向前端推送,页面效果和 SSE 看起来一模一样。
- 特点:支持文本、二进制;浏览器没有自动重连,需要自己写代码处理断线。
- 适用场景:聊天、在线游戏、协同编辑;前后端需要频繁互相发送消息。