跳转至

WebSocket 在实时 IoT 中的角色

难度:🟡 中级 | 领域:实时通信、Web IoT | 阅读时间:约 20 分钟

日常类比

超文本传输协议(Hypertext Transfer Protocol, HTTP)轮询像反复寄信问「有新消息吗」;长轮询像对方压着信等有货再回,但每次仍要再寄一封。WebSocket 像通电话:一次拨号后双方随时说话。物联网(Internet of Things, IoT)传感器可推数据,服务器可下发指令。代价是每条「通话」占连接与内存——设备规模上去后,连接数本身成为瓶颈[1][6]。

摘要

本文对比轮询、长轮询、服务器推送事件(Server-Sent Events, SSE)与 WebSocket,说明握手与帧开销、受限设备实现、MQTT over WebSocket、仪表盘集成与水平扩展。延迟与每连接内存等数字高度依赖运行时与消息速率,宜作量级参考[6][9]。

1 实时方案对比

特性 HTTP 轮询 HTTP 长轮询 SSE WebSocket
方向 客户端→服务器为主 同左 服务器→客户端 全双工
连接 短连接频繁建 挂起后重建 持久单向 持久双向
延迟倾向 受轮询间隔限制
二进制 需编码 需编码 文本为主 原生
穿透防火墙 最好 依赖代理对 Upgrade 支持
每消息开销倾向 完整 HTTP 头 完整 HTTP 头 较小 帧头通常数字节级[1]

同机房、TLS 条件下,已建立的 WebSocket 上后续小消息往返常明显低于反复 HTTP;带宽上帧头相对 HTTP 头可低一到两个数量级——具体毫秒与 GB/小时随载荷与心跳而变[6]。

2 协议机制

2.1 握手

客户端发 HTTP Upgrade: websocket,带 Sec-WebSocket-Key;服务器回 101 Switching ProtocolsSec-WebSocket-Accept。可协商子协议(如 mqtt)[1]。生产环境应使用 WSS(WebSocket over TLS)。

2.2 帧

帧含 FIN、opcode、掩码位与载荷长度;浏览器客户端发往服务器的帧必须掩码。IoT 小 JSON(数十字节载荷)时,帧头相对 HTTP 头节省显著;高频场景可再考虑 MessagePack/Protobuf 与可选压缩扩展(RFC 7692),权衡 CPU[2]。

3 受限设备上的 WebSocket

平台倾向 每连接 RAM 量级 代码体积量级 并发连接
ESP32 类 十余 KB 起 数十 KB 个位数~数十(视堆)
ESP8266 类 相近或更紧 更紧 更少
LwIP MCU 常更省 视裁剪
Linux 网关 数十 KB 起(含缓冲) N/A 可达数万级(调优后)

数字来自厂商文档与社区测量的量级,与 TLS、缓冲与库实现强相关[5]。设备侧务必配置心跳、超时重连与证书校验;深度睡眠设备更适合短连上报,而非强行 always-on WebSocket。

4 MQTT over WebSocket

浏览器不能随意开原始 MQTT TCP;企业网常只放行 443。将 MQTT 控制报文装进 WebSocket 帧,可由 Broker(Mosquitto / EMQX / HiveMQ 等)同时监听 TCP 与 WS/WSS[3][4][8]。

路径 典型端口叙事 角色
MQTT TCP 1883 / 8883 设备原生
MQTT WS/WSS 8083 / 8084 等 浏览器、仅 HTTP 出口的网关

配置要点:限制 Origin、TLS 双向或令牌认证、max_connections 与路径(如 /mqtt)与前端库一致[4]。

5 仪表盘:原生 WS 与 Socket.IO

特性 原生 WebSocket Socket.IO 等
重连/房间 自建 常内置
降级 可回落长轮询
开销 更接近标准帧 额外封装
适用 延迟与带宽敏感 快速出活

浏览器侧常用 MQTT.js 经 WSS 连 Broker,订阅 sensors/+/data,向 devices/{id}/commands 发布控制[3]。

6 扩展与安全

连接上限受文件描述符、每连接内存与事件循环处理心跳/消息的能力约束。空闲连接可远多于「每连接每秒多条消息」时的容量——规划必须以目标消息速率压测[9]。

水平扩展:七层负载均衡需粘滞(cookie / IP hash);跨节点广播可用 Redis Pub/Sub、NATS 等,延迟与持久化需求不同。

安全清单:仅 WSS;校验 Origin;握手或首消息鉴权;每连接速率与载荷上限;Ping/Pong 清僵尸连接;每设备连接数限制[10]。

7 局限、挑战与可改进方向

1. 连接数叙事易低估消息成本

局限:宣传「单机数十万连接」常指空闲;IoT 定时上报会把瓶颈转到 CPU 与带宽[9]。 改进:按「连接数 × 每秒消息 × 载荷」建模;网关聚合后再上 WebSocket/MQTT。

2. 中间盒与休眠设备

局限:劣质代理缓冲或切断 Upgrade;NAT 超时杀死长连接;MCU 睡眠导致半开连接。 改进:心跳取 NAT 超时一半量级并实测;睡眠设备改短生命周期连接;运维监控升级失败率。

3. 安全默认值不足

局限:示例常关 Origin 检查、把令牌放进长期 URL,易泄露与 CSRF 类风险[10]。 改进:短时令牌、强制 WSS、Broker 侧 ACL 与每主题速率限制。

4. 与 MQTT QoS 语义叠加复杂

局限:WebSocket 只保证传输帧,MQTT QoS 重传与会话在 Broker/客户端;断线风暴会放大[3]。 改进:指数退避+抖动重连;清晰 clean start/会话恢复策略;关键指令用可幂等设计。

8 实践要点

  1. 用浏览器 DevTools Network → WS 观察帧与关闭码。
  2. 本地 Mosquitto/EMQX 开 WSS,MQTT.js 联调仪表盘。
  3. 压缩与二进制编码先做 CPU/电量对比再默认开启。
  4. 压测区分空闲连接与业务消息速率两种剖面。

参考文献

[1] RFC 6455, "The WebSocket Protocol," IETF, 2011. [2] RFC 7692, "Compression Extensions for WebSocket," IETF, 2015. [3] OASIS, "MQTT Version 5.0," 2019 (WebSocket transport bindings / broker docs). [4] EMQX Documentation, "WebSocket Listener Configuration." [5] Espressif, "ESP-IDF WebSocket Client API Reference." [6] V. Karagiannis et al., "WebSocket Performance for IoT Applications," IEEE Access, 2023. [7] Socket.IO, "Engine.IO Protocol / How it Works." [8] Eclipse Mosquitto, WebSocket configuration documentation. [9] D. Pavlovic et al., "Scalable WebSocket Architecture for IoT," ACM IoT-related venue, 2024. [10] Industry guidance on WebSocket security (e.g., Cloudflare and OWASP-related practices). [11] RFC 8441, "Bootstrapping WebSockets with HTTP/2," IETF, 2018.