Skip to content

WebSocket 与长连接

握手升级、双向通信、心跳保活、与 SSE/轮询对比。

Updated View as Markdown
For humans

WebSocket 与长连接

HTTP 是“请求响应”模式,服务端不能主动推送。WebSocket 把连接升级为全双工长连接。面试主线:握手怎么升级、心跳怎么保活、和替代方案怎么选。

握手:HTTP 升级

WS 握手: 普通 HTTP 请求升级为长连接

  • 握手就是普通 HTTP 请求带 Upgrade: websocket 头,服务端回 101 切换协议
  • 之后同一 TCP 连接上双向发帧(文本/二进制)
  • 关键头:Sec-WebSocket-Key(客户端随机)→ 服务端算 Sec-WebSocket-Accept 返回(防缓存代理误升级)

为什么需要心跳

长连接空闲时可能被中间设备(NAT、防火墙、LB)静默断开,双方都不知道

  • 被动关闭:客户端发的包被 NAT 丢弃,卡死等超时(体验差)
  • 解法:应用层心跳(ping/pong 帧或自定义),周期互发,超时判定死连接并重连
客户端 → ping → 服务端 → pong(或业务消息)
N 秒没收到 pong → 判定断线 → 重连

生产要点:心跳间隔要小于中间设备空闲超时(LB 常见 60s,心跳 30s 左右);服务端也要统计最近活跃时间,超时主动踢。

三种推送方案对比

方案 方向 机制 适用
轮询 客户端拉 定时 HTTP 请求 简单,延迟和流量是矛盾
SSE 服务端推 HTTP 长响应(text/event-stream) 单向推送(通知、补全)
WebSocket 双向 升级后的全双工 聊天、协作、实时交互

选型:单向推送用 SSE(更简单,自动重连),双向交互用 WebSocket。轮询是兜底(兼容、简单)。

生产注意

  • 多实例:WS 连接粘在单实例,广播要 Redis pub/sub(见 FastAPI 生产部署篇)
  • 连接数:每连接有内存开销,单机万级要规划;心跳风暴要限频
  • 网关:Nginx/LB 要配 WS 支持(Upgrade 头透传、空闲超时调大)

面试追问

  1. WebSocket 握手是什么? 普通 HTTP 请求带 Upgrade 头,服务端回 101。之后同一 TCP 双向通信
  2. 为什么需要心跳? 中间设备静默断连接,双方无感知。心跳探测 + 超时重连
  3. SSE 和 WebSocket? SSE 单向(HTTP 长响应、自动重连),WS 双向。单向推送用 SSE 更简单
  4. 多实例怎么广播? WS 粘在单实例,用 Redis pub/sub 跨实例分发(见 FastAPI 篇)
  5. 心跳间隔怎么定? 小于中间设备空闲超时(LB 常见 60s 就设 30s 左右),太频繁是浪费
Navigation

Type to search…

↑↓ navigate↵ selectEsc close