websocket适合浏览器或app与后端强状态、低延迟双向交互且连接数可控的场景,如在线聊天、实时协作;mqtt更适合海量设备接入、弱网容忍、离线消息保障的iot场景。

选 WebSocket 还是 MQTT,不看文档、不比参数,直接看你的服务端扛不扛得住百万连接、消息丢没丢、前端能不能直接连设备、断网后重连要不要手动补数据——这些才是真实压测现场暴露的问题。
WebSocket 适合“谁在跟谁说话”场景
当你需要浏览器或 App 端和后端保持强状态、低延迟双向交互,且连接数可控(比如单集群 WebSocket 是最省事的选择。
- 典型场景:在线协作文档光标同步、股票行情推送、客服聊天窗口
- 连接建立快,
ws://或wss://地址一行就能连上,前端用new WebSocket()即可,无额外依赖 - 但服务端必须自己维护连接生命周期:用户在哪台机器上、掉线了怎么通知其他端、群聊消息要广播给哪些人——这些全靠你写逻辑,常见用
Redis Pub/Sub或Kafka做跨节点同步 - 没有内置重传或离线缓存,断网重连后,中间漏掉的消息除非你额外加序列号+服务端消息回溯,否则就真丢了
MQTT 适合“消息发出去,不管谁收”场景
当你面对的是成千上万的设备、网络不稳定、消息不能丢、还要支持离线订阅、主题路由、分级可靠性,那 MQTT 不是选项,是刚需。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 典型场景:温湿度传感器批量上报、电动车远程锁车指令下发、智能家居联动触发
-
MQTT的Broker(如EMQX、Mosquitto)自带会话管理:设备断开后,只要用cleanSession: false,重连时能自动收到离线期间发到它订阅的Topic的消息 -
QoS 1保证“至少一次”,QoS 2保证“恰好一次”,而WebSocket没有等价机制,你要自己实现 ACK + 重发队列 - 注意:MQTT 默认走
tcp://(端口1883),若需浏览器直连,得用MQTT over WebSocket(即wss://broker.example.com:8084/mqtt),此时 Broker 必须开启 WebSocket 监听,并配置好 TLS
前端连不上 MQTT Broker?别硬刚,换一层封装
浏览器原生不支持 mqtt://,直接 new Paho.MQTT.Client() 或 mqtt.js 连 1883 端口必然失败——这是 CORS 和协议栈限制,不是配置问题。
- 正确路径只有两条:
MQTT over WebSocket(Broker 开启 ws/wss 支持),或后端起一个WebSocket代理,把前端ws请求转成mqtt协议发给 Broker - 用
MQTT over WebSocket时,Broker 配置里必须显式启用websocketlistener,例如 EMQX 的etc/emqx.conf要有:listener.ws.external = 8083,且路径需匹配前端 client 初始化时的path参数(常见为/mqtt) - 别信“前端用 mqtt.js 就能直连任意 MQTT 服务”的说法——它只解决编码/解码,不解决传输层握手。连不上,先查 Broker 日志有没有
websocket accept记录,再抓包看是不是卡在 HTTP Upgrade 阶段
混合架构才是高并发实时系统的事实标准
纯 WebSocket 架构撑不过 10 万连接;纯 MQTT 架构让前端开发骂娘。真正跑得稳的系统,基本都用 “前端 ↔ WebSocket 接入层 ↔ MQTT Broker” 三层结构。
- 接入层(如 Node.js +
ws库)只做协议转换:把前端发来的 JSON 消息按规则映射成publish到某个Topic,把从subscribe收到的 MQTT 消息转发给对应 WebSocket 连接 - 好处明显:前端不用懂 MQTT,后端不用管连接状态,Broker 专注消息分发,各层可独立扩缩容
- 容易被忽略的坑:
Topic设计要收敛,避免前端动态拼接/user/{id}/cmd类路径导致 Broker 路由爆炸;建议统一用固定前缀 + ID 字段传参,比如cmd/user+ payload 中带{"uid": "123"}
协议选择最终卡在运维成本和消息语义上:如果你的“实时”要求消息必达、设备随时上下线、Topic 动态变化频繁,MQTT 的 Broker 就不是组件,是基础设施;如果只是让几个页面互相喊话,WebSocket 连上就开干,别给自己加戏。










