实时通信
在实时通信场景中,有WebSocket、轮询,SSE多种方式。
| 技术 | 通信方向 | 核心特征 |
|---|---|---|
| WebSocket | 全双工通信(客户端 ↔ 服务器):双方可同时发送 / 接收数据,连接建立后双向实时交互 | - 基于 TCP 协议,握手后保持长连接- 无请求头冗余,传输效率高- 支持二进制 / 文本数据,适用于高频实时场景 |
| SSE(Server-Sent Events) | 半双工通信(服务器 → 客户端):仅服务器向客户端单向推送数据,客户端需通过单独 HTTP 请求反馈 | - 基于 HTTP 协议,长连接(连接建立后保持)- 仅支持文本数据,客户端被动接收,无法主动向服务器发数据- 自带重连机制,适合服务器向客户端单向推送场景 |
| 轮询(Polling) | (客户端 → 服务端)客户端单向请求 → 服务器被动响应(客户端 → 服务器 → 客户端):客户端定时发送 HTTP 请求查询新数据 | - 基于 HTTP 协议,短连接(每次请求后断开)- 存在空响应(无新数据时),浪费带宽和服务器资源- 实时性取决于轮询间隔(间隔越短越实时,但开销越大) |
补充说明(面试高频考点)
-
WebSocket 全双工场景:即时聊天(如微信网页版)、实时协作工具(如在线文档)、游戏实时交互,需双方高频双向通信;
-
SSE 半双工场景:实时数据展示(如股票行情、监控面板)、新闻推送,仅需服务器向客户端单向推送,无需客户端主动发送数据。
-
轮询适用场景 :早期无更好方案时的简单实时需求(如简陋的消息通知),现已基本被 WebSocket/SSE 替代;
WebSocket
WebSocket 是一种基于 TCP 连接的全双工(双向)通信协议,即客户端和服务器可以同时发送和接收数据。
WebSocket 协议本质上是应用层的协议 ,用于弥补 HTTP 协议在持久通信能力上的不足。客户端和服务器仅需一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
几乎所有主流较新版本的浏览器都支持该协议。不过,WebSocket 不只能在基于浏览器的应用程序中使用,很多编程语言、框架和服务器都提供了 WebSocket 支持。
工作过程
-
请求 :客户端向服务器发送一个 HTTP 请求,请求头中包含
Upgrade: websocket和Sec-WebSocket-Key等字段,表示要求升级协议为 WebSocket; -
响应 :服务器收到这个请求后,会进行升级协议的操作,如果支持 WebSocket,它将回复一个 HTTP 101 状态码,响应头中包含 ,
Connection: Upgrade和Sec-WebSocket-Accept: xxx等字段、表示成功升级到 WebSocket 协议。 -
建立连接:客户端和服务器之间建立了一个 WebSocket 连接,可以进行双向的数据传输。数据以帧(frames)的形式进行传送,WebSocket 的每条消息可能会被切分成多个数据帧(最小单位)。发送端会将消息切割成多个帧发送给接收端,接收端接收消息帧,并将关联的帧重新组装成完整的消息。
-
关闭连接:客户端或服务器可以主动发送一个关闭帧,表示要断开连接。另一方收到后,也会回复一个关闭帧,然后双方关闭 TCP 连接。
另外,建立 WebSocket 连接之后,通过心跳机制来保持 WebSocket 连接的稳定性和活跃性。
应用场景
-
视频弹幕
-
实时消息推送
-
实时游戏对战
-
多用户协同编辑
-
社交聊天
与HTTP的区别
WebSocket 和 HTTP 两者都是基于 TCP 的应用层协议,都可以在网络中传输数据。
下面是二者的主要区别:
-
通信双向:WebSocket 是一种双向实时通信协议,而 HTTP 是一种单向通信协议。并且,HTTP 协议下的通信只能由客户端发起,服务器无法主动通知客户端。
-
协议前缀 :WebSocket 使用
ws:// 或 wss://(使用 SSL/TLS 加密后的协议,类似于 HTTP 和 HTTPS 的关系) 作为协议前缀,HTTP 使用http:// 或 https://作为协议前缀。 -
可拓展性:WebSocket 可以支持扩展,用户可以扩展协议,实现部分自定义的子协议,如支持压缩、加密等。
-
轻量性:WebSocket 通信数据格式比较轻量,用于协议控制的数据包头部相对较小,网络开销小,而 HTTP 通信每次都要携带完整的头部,网络开销较大(HTTP/2.0 使用二进制帧进行数据传输,还支持头部压缩,减少了网络开销)
与SSE的区别
通信方式:
-
SSE: 单向通信。只有服务器能向客户端(浏览器)发送数据。客户端不能通过同一个连接向服务器发送数据(需要发起新的 HTTP 请求)。
-
WebSocket: 双向通信 (全双工)。客户端和服务器可以随时互相发送消息,实现真正的实时交互。
底层协议:
-
SSE: 基于标准的 HTTP/HTTPS 协议 。它本质上是一个"长连接"的 HTTP 请求,服务器保持连接打开并持续发送事件流。不需要特殊的服务器或协议支持,现有的 HTTP 基础设施就能用。响应头应里包含
text/event-stream。 -
WebSocket: 使用独立的 ws:// 或 wss:// 协议。它需要通过一个特定的 HTTP "Upgrade" 请求来建立连接,并且服务器需要明确支持 WebSocket 协议来处理连接和消息帧。
实现复杂度和成本:
-
SSE: 实现相对简单,主要在服务器端处理。浏览器端有标准的 EventSource API,使用方便。开发和维护成本较低。
-
WebSocket: 稍微复杂一些。需要服务器端专门处理 WebSocket 连接和协议,客户端也需要使用 WebSocket API。如果需要考虑兼容性、心跳、重连等,开发成本会更高。
断线重连:
-
SSE: 浏览器原生支持。EventSource API 提供了自动断线重连的机制。
-
WebSocket: 需要手动实现。开发者需要自己编写逻辑来检测断线并进行重连尝试。
数据类型:
-
SSE: 主要设计用来传输文本 (UTF-8 编码)。如果需要传输二进制数据,需要先进行 Base64 等编码转换成文本。
-
WebSocket: 原生支持传输文本和二进制数据,无需额外编码。
为了提供更好的用户体验和利用其简单、高效、基于标准 HTTP 的特性,Server-Sent Events (SSE) 是目前大型语言模型 API(如 OpenAI、DeepSeek 等)实现流式响应的常用技术选择