Skip to main content

WebSocket

面试一句话总结:WebSocket 是一种基于 TCP 的全双工、双向通信协议。它借用 HTTP 协议完成一次握手升级(状态码 101),之后便摆脱 HTTP 的束缚,以极低开销的二进制帧进行实时数据传输。常用于聊天室、协同编辑和实时大屏。

1. 核心工作原理

WebSocket 虽然名字里带 Web,但它实际上是一个独立的协议(ws:// 或加密的 wss://),它只是在“建立连接”这个阶段“蹭”了一下 HTTP 的车。

① 协议升级 (HTTP 握手)

建立连接时,客户端会发送一个标准的 HTTP GET 请求,并在请求头中要求“升级协议”:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

服务端如果支持 WebSocket,会返回 101 Switching Protocols 状态码,并计算一个 Sec-WebSocket-Accept 返回给客户端。 至此,HTTP 功成身退,这条 TCP 连接被 WebSocket 正式接管。

② 数据传输格式 (帧 Frame)

与 HTTP 每次请求都携带几百字节的臃肿 Header 不同,WebSocket 传输数据时使用的是帧 (Frame) 格式,帧头极小(通常只有 2~10 个字节)。 它原生支持传输文本(Text)以及二进制数据(ArrayBufferBlob),非常适合音视频流传输。


2. 与 HTTP 及 SSE 的对比 (高频考点)

在高级面试中,面试官往往会让你对比这几种通信方案的选型。

特性HTTP (轮询/长轮询)SSE (Server-Sent Events)WebSocket
通信方向半双工 (单向)单向 (服务端推给客户端)全双工 (双向)
协议层HTTPHTTPWebSocket (独立协议)
重连机制浏览器原生支持自动重连需手写心跳保活和断线重连
头部开销极大 (每次带完整 Header)较大极小 (2~10 字节帧头)
适用场景低频数据请求AI 打字机、股票大屏、消息通知IM 聊天、协同编辑、在线游戏

实战选型思考: 如果业务需求只是“服务端向客户端单向推数据”(如 ChatGPT 的回复、系统广播),绝对优先选择 SSE。它更轻量,且原生支持断线重连。只有在需要高频、实时的双向交互时,才动用 WebSocket 这个重型武器。


3. 工程实战与难点解决

如果在简历里写了 WebSocket,面试官一定会问你如何保证连接的稳定性。

① 心跳检测 (Ping/Pong 保活)

痛点:TCP 长连接在长时间没有数据传输时,很容易被中间的网络设备(如 Nginx、防火墙、运营商 NAT)当作死连接而偷偷掐断,此时前端根本感知不到(触发不了 onclose)。 解法:前端需要实现心跳机制。每隔固定的时间(如 30 秒)向服务端发送一个内容为 Ping 的空帧,服务端收到后立刻回复 Pong。如果前端连续几次发了 Ping 却没有收到 Pong,就认为连接已死,主动执行重连。

② 优雅的断线重连 (指数退避算法)

痛点:当服务器宕机或网络抖动导致连接断开时(触发 onclose / onerror),如果几万个客户端同时疯狂重试,会导致服务器瞬间被打挂(类似 DDoS 攻击)。 解法:使用指数退避算法(Exponential Backoff)。重试间隔不是固定的,而是成倍增加(如 1s, 2s, 4s, 8s, 16s...),并且还要加上一段随机抖动时间 (Jitter),打散客户端的重连请求峰值。

③ 身份鉴权问题

痛点:WebSocket 无法像 HTTP 请求那样,利用拦截器在 Header 里方便地带上 Authorization: Bearer Token解法

  1. URL 传参(最常见但有安全隐患):ws://api.com?token=xxx。缺点是 Token 容易记录在网关的访问日志中。
  2. 连接后第一条消息鉴权(最安全):建立连接后,服务端不接受任何业务指令,要求前端先发一条专门的 {"type": "auth", "token": "xxx"} 消息。服务端校验通过后才放行,否则直接掐断连接。

4. 安全防护 (WSS)

  • WSS 协议:生产环境必须使用 wss:// 代替 ws://。它在 TLS 层上进行了加密(类似于 HTTPS),能有效防止抓包和中间人攻击。
  • 跨站 WebSocket 劫持 (CSWSH):类似于 HTTP 的 CSRF 攻击。恶意网站可以通过 JS 直接向你的服务端发起 WebSocket 连接。防范方案:服务端在握手阶段,必须严格校验 HTTP 请求头中的 Origin 字段是否在白名单内。