MQTT是消息协议,需Broker中转,专注消息语义与可靠性;WebSocket是浏览器直连的双向通道,不处理消息逻辑;生产中常用MQTT over WebSocket组合,兼顾接入性与消息能力。

没有“哪个好”这回事,只有“在哪用、怎么搭”才决定选哪个。MQTT 和 WebSocket 不是同一类东西,硬要比谁更好,就像问“螺丝刀和水泥哪个盖楼更好”——得看你是拧螺丝还是浇地基。
MQTT 是消息协议,不是传输通道
它定义的是“消息怎么发、给谁、要不要确认、断线了怎么办”。你不能直接 new MQTT(),必须依赖 Broker(比如 Mosquitto、EMQX)做中转。设备端用 client.publish() 发到 /sensor/temperature,所有订阅该 Topic 的 App、数据库、告警服务都会收到,互不感知。
常见错误现象:
- 直接在浏览器里用原生 JS 调
mqtt.connect('mqtt://...')—— 失败,因为浏览器不支持裸 TCP 连接 - 没配
clean: false和keepalive,设备掉线后收不到离线消息 - 把 QoS 1 当成“一定只收一次”,结果因重传机制导致重复消费(QoS 1 是“至少一次”,不是“恰好一次”)
WebSocket 是浏览器能直接用的双向通道
它只管建立连接、收发数据帧,不管内容格式、不负责路由、不保证送达。你得自己约定 JSON 结构、加消息 ID、写重发逻辑、维护用户在线状态映射表。
使用场景:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 网页后台实时显示设备在线状态(每秒拉一次?别傻了,用
ws.onmessage推) - 运维人员在 Web 界面点“重启设备”,前端通过 WebSocket 直连边缘网关下发指令
- 股票行情页需要毫秒级更新,且只推给当前打开该页面的用户(无广播需求)
性能影响:每个 WebSocket 连接都占一个服务端长连接资源;1000 个用户 = 1000 个连接,而 MQTT 下 1000 个设备可能共用同一个 Broker 连接池 + Topic 分发。
MQTT over WebSocket 是真实生产环境的标配组合
这不是妥协,而是取两者所长:用 WebSocket 解决浏览器接入问题,用 MQTT 解决消息语义和可靠性问题。Broker(如 EMQX)本身支持 wss:// 端点,前端用 mqtt.connect('wss://broker.example.com:8084/mqtt') 就能走标准 MQTT 协议。
关键配置注意点:
- 路径必须带
/mqtt(或 Broker 配置的 WebSocket 路由前缀),否则握手失败报404 - 跨域问题不靠 CORS 解,得在 Broker 配置
allow_origins或设为* - 浏览器端无法用
retain消息自动补发,因为会话生命周期受页面控制;想保消息,得靠 Broker 的持久会话 +clean: false
复杂点往往藏在“谁管状态”这件事上
WebSocket 连接断开,服务端立刻丢掉这个 socket 引用,除非你额外存 Redis 记录用户身份和最后连接时间;MQTT 的 will 遗嘱消息和 session expiry interval 是协议层内置的,设备掉电瞬间 Broker 就能发通知。别指望用 WebSocket 自己实现一套等效机制——成本远高于换用 MQTT over WebSocket。

















