WebSocket 与 MQTT 在即时通讯中的对比与架构选型指南
先把结论说清楚
WebSocket 和 MQTT 都能用于即时通讯,但它们解决的问题并不完全一样。
-
WebSocket 更像“浏览器时代的实时双向通道”
- 适合 Web 端聊天、在线状态、消息推送、协同编辑、行情订阅这类场景
- 优势在于浏览器原生支持好、接入简单、协议灵活
- 劣势在于消息可靠性、会话管理、离线补偿、主题路由这些能力需要业务自己补
-
MQTT 更像“面向弱网和大规模连接的消息分发协议”
- 适合移动端弱网、IoT 设备、车联网、硬件终端、边缘节点、跨网络环境推送
- 优势在于轻量、低带宽、QoS、保活、主题订阅、断线重连模型成熟
- 劣势在于浏览器端原生支持不如 WebSocket 直接,业务语义表达也没有 WebSocket 那么自由
如果你的系统核心是Web 聊天产品,优先考虑 WebSocket。 如果你的系统核心是大规模终端接入、弱网消息传递、设备在线控制,优先考虑 MQTT。 如果你的系统既有 App/Web IM,又有设备侧或消息网关侧复杂接入,通常会落到WebSocket + MQTT 混合架构。
为什么这两个协议总被拿来比较
即时通讯系统本质上都绕不开几个问题:
- 如何建立长连接
- 如何让服务端主动推消息给客户端
- 如何在弱网下保持连接稳定
- 如何处理离线、重连、重复投递、消息顺序
- 如何支持大规模连接与水平扩展
WebSocket 和 MQTT 都能建立长连接,也都支持双向通信,所以表面上看起来都能做 IM。 但真正到了架构设计阶段,它们的差异会非常明显:WebSocket 偏“通道能力”,MQTT 偏“消息协议能力”。
这就是为什么它们经常会被放在一起讨论。
WebSocket 的本质:一条持续存在的全双工 TCP 通道
WebSocket 基于 HTTP 握手升级连接,建立成功后,客户端和服务端之间会保持一条长期存在的双向连接。
它最大的价值不在“能发消息”,而在于:
- 服务端可以主动向客户端推送数据
- 客户端也可以随时向服务端发送数据
- 避免传统 HTTP 轮询带来的高延迟和高开销
对于即时通讯来说,这意味着:
- 用户发消息时,不需要重新建立连接
- 服务端有新消息时,可以立刻推送给在线用户
- 在线状态、输入状态、回执状态都能实时同步
WebSocket 的典型特点
-
浏览器支持非常成熟
- 前端可直接使用
WebSocketAPI - 不需要额外插件或复杂协议栈
- 前端可直接使用
-
协议层约束少
- 传什么格式都行:JSON、Protobuf、二进制都可以
- 非常适合业务自定义协议
-
开发自由度高
- 聊天消息、心跳、在线状态、ACK、房间订阅,都可以自己定义
-
协议本身不解决消息可靠性
- 是否确认送达
- 是否支持重发
- 是否有 QoS
- 是否断线续传 这些都不是 WebSocket 原生解决的,需要业务层自己实现
这意味着什么
WebSocket 适合做“实时交互”,但它只是提供了一条实时通道。 通道之上的消息语义、可靠性和分发规则,需要你自己设计。
MQTT 的本质:一个带发布订阅语义的轻量消息协议
MQTT 最初就是为低带宽、不稳定网络和远程设备通信设计的。 它不是简单的“长连接协议”,而是一套完整的消息发布/订阅协议。
MQTT 有几个核心角色:
- Client:客户端,既可以发布消息,也可以订阅主题
- Broker:消息代理,负责接收、路由、分发消息
- Topic:主题,用来组织消息路由路径
比如:
- 用户 A 发消息到
chat/private/user_1001 - 用户 B 订阅
chat/private/user_1001 - Broker 负责把消息投递给对应订阅者
MQTT 的典型特点
-
天然发布/订阅模型
- 路由模型成熟,不必自己发明“频道、房间、订阅机制”
-
为弱网环境优化
- 报文头小
- 带宽占用低
- 保活机制明确
-
支持 QoS
- QoS 0:最多一次
- QoS 1:至少一次
- QoS 2:仅一次
-
支持保留消息、遗嘱消息、会话持续
- 很适合在线状态同步、离线状态通知、设备上下线感知
-
Broker 成为架构核心
- 客户端不直接互连
- 所有消息都经过 Broker 路由
- 更适合大规模连接治理
版本差异要明确
MQTT 3.1.1
这是目前很多中间件和历史系统里仍然广泛使用的版本,特点是:
- 协议成熟
- 实现广泛
- 功能相对朴素
- 适合大多数基础消息场景
MQTT 5.0
MQTT 5.0 在 3.1.1 基础上增加了更多工程能力,例如:
- 更丰富的原因码
- 用户属性
- 消息过期间隔
- 请求/响应模式支持增强
- 流控和错误语义更明确
如果是新系统,优先考虑 MQTT 5.0; 如果你的 Broker、客户端 SDK、网关体系仍主要围绕旧生态建设,MQTT 3.1.1 仍然是现实可行选择。
从即时通讯的核心维度逐项对比
1. 连接建立与客户端接入
WebSocket
- 基于 HTTP/HTTPS 升级,和现有 Web 系统集成自然
- 浏览器原生支持,前端接入成本极低
- 对 Web 应用尤其友好
MQTT
- 通常基于 TCP,也可跑在 WebSocket 之上
- 原生更适合 App、设备、嵌入式终端
- 浏览器端如果用 MQTT,通常是 MQTT over WebSocket
判断
- 纯 Web 聊天:WebSocket 更直接
- 设备 + App + 后台系统统一接入:MQTT 更整齐
2. 消息模型
WebSocket
WebSocket 只是传输管道,没有内建消息模型。 你需要自己定义:
- 消息类型
- 消息编号
- 消息 ACK
- 重试策略
- 订阅关系
- 路由规则
例如你可能会自定义:
{
"type": "chat_message",
"msgId": "a8f1c9",
"from": 1001,
"to": 1002,
"timestamp": 1710000000,
"payload": {
"content": "你好"
}
}
然后还要再定义:
ackheartbeattypingread_receiptjoin_roomleave_room
MQTT
MQTT 的消息模型天然就是:
- 发布到某个主题
- 订阅某个主题
- Broker 负责转发
你只要设计好 Topic 体系,例如:
im/user/1001/inboxim/group/2001/messagesim/presence/1001im/system/notice
判断
- 业务协议高度定制、灵活性优先:WebSocket 更自由
- 消息路由和订阅关系复杂:MQTT 更省事
3. 消息可靠性
这是两者差异最大的点之一。
WebSocket
WebSocket 本身不保证业务消息一定送达。 TCP 能保证字节流传输,但不能替你解决这些业务问题:
- 客户端收到了没有
- 客户端处理成功没有
- 断线期间漏掉的消息怎么办
- 服务端重发后如何去重
- 多端登录如何协调回执状态
所以基于 WebSocket 做 IM,通常都要自己实现:
- 业务消息 ID
- 服务器 ACK
- 客户端 ACK
- 重试机制
- 去重机制
- 离线补拉
MQTT
MQTT 原生支持 QoS:
- QoS 0:不保证到达,性能最高
- QoS 1:至少一次,可能重复
- QoS 2:仅一次,最重
看起来 MQTT 完胜,但要注意两个现实问题:
-
QoS 不是“聊天业务可靠性”的全部
- 它解决的是协议层投递语义
- 不是已读、送达、会话一致性、历史同步这些完整业务语义
-
QoS 2 成本高
- 流程更重
- 吞吐更低
- 大规模 IM 系统里通常不会滥用
判断
- 想快速获得协议层可靠性能力:MQTT 更强
- 需要复杂业务可靠性闭环:两者都要做业务层补充,只是 MQTT 起点更高
4. 弱网适应能力
WebSocket
WebSocket 在正常网络下体验很好,但到移动网络、网络抖动、频繁切换基站、后台挂起等场景,往往需要较多补偿逻辑:
- 心跳间隔控制
- 断线检测
- 指数退避重连
- 网络恢复后增量同步
- 前后台切换时连接恢复
MQTT
MQTT 天生就是为这类环境设计的:
- 报文轻
- Keep Alive 明确
- 清理会话与持久会话机制成熟
- Broker 侧对连接状态管理更统一
判断
- 移动端弱网、IoT、车机、边缘网络:MQTT 明显更有优势
- 内网或稳定公网 Web 场景:WebSocket 完全够用
5. 服务端路由和扩展能力
WebSocket
WebSocket 做到一定规模后,服务端通常会面临这些问题:
- 长连接如何分布到多台节点
- 用户连接在哪台机器上
- 点对点消息如何跨节点投递
- 群消息如何广播给分散在多台机器上的连接
- 如何做会话迁移和水平扩容
所以 WebSocket IM 系统通常需要额外引入:
- 网关层
- 用户连接映射表
- Redis / Kafka / MQ 作为跨节点分发总线
- 在线路由服务
- 离线消息存储
也就是说,WebSocket 把复杂性推给了你的服务端架构。
MQTT
MQTT 把消息路由中心抽象成 Broker。 Broker 本身就负责:
- 连接管理
- 订阅关系维护
- 消息转发
- 会话管理
这会让系统架构更清晰,但同时也意味着:
- Broker 成为关键基础设施
- 集群、持久化、限流、鉴权、主题规划都必须设计好
- 主题爆炸、订阅风暴、权限粒度问题会在中后期暴露出来
判断
- 想快速搭建通用实时网关:WebSocket 常见
- 想让消息路由中心化治理:MQTT 更合适
6. 浏览器生态支持
WebSocket
这是 WebSocket 最大优势之一:
- 浏览器原生支持
- CDN、反向代理、负载均衡生态成熟
- 前端开发体验好
MQTT
浏览器不能直接原生跑纯 MQTT/TCP。 一般要通过:
- MQTT over WebSocket
- 第三方 SDK
这意味着浏览器端用 MQTT 时,实际上仍然是借助 WebSocket 承载。
判断
- Web 前端是主战场:WebSocket 胜出
- 浏览器只是众多终端之一:MQTT 仍可接受
7. 协议开销与性能
这部分不能简单说“谁一定更快”,因为性能取决于:
- 消息体大小
- 连接数
- 心跳频率
- 序列化格式
- 服务端实现
- 是否跨机房
- 是否做持久化
但从协议设计上说:
WebSocket
- 协议头不算重
- 适合实时传输
- 但很多系统实际传 JSON,业务包体较大
- 灵活也意味着容易写得臃肿
MQTT
- 协议头更轻
- 主题路由明确
- 对小消息、频繁消息、弱网消息非常友好
判断
- 轻量高频小消息:MQTT 通常更占优
- 复杂业务消息、前端交互消息:WebSocket 足够且更灵活
8. 安全与权限控制
无论用 WebSocket 还是 MQTT,即时通讯都至少要解决:
- 用户身份认证
- 连接鉴权
- 消息发送权限
- 订阅权限
- 群组成员校验
- 防刷与限流
WebSocket
通常做法是:
- 握手时带 Token
- 网关校验后建立连接
- 后续业务消息再按会话和权限校验
MQTT
除了连接鉴权,还要重点处理:
- Topic 读写权限
- 通配符订阅权限
- 多租户 Topic 隔离
- Broker 侧 ACL 策略
判断
- WebSocket 的安全复杂度在业务层
- MQTT 的安全复杂度在 Broker 权限模型 + 业务层
核心差异,用一张表看明白
| 对比维度 | WebSocket | MQTT |
|---|---|---|
| 协议定位 | 双向实时传输通道 | 轻量级发布/订阅消息协议 |
| 浏览器支持 | 原生支持,非常成熟 | 通常通过 MQTT over WebSocket |
| 消息模型 | 需要业务自定义 | 原生 Topic Pub/Sub |
| 可靠性能力 | 需业务层自己实现 ACK/重试/补偿 | 原生支持 QoS |
| 弱网适应 | 一般,需较多补偿逻辑 | 强,设计目标之一 |
| 路由能力 | 需业务自己做分发架构 | Broker 原生支持 |
| 协议灵活性 | 很高 | 中等,受 Topic 模型约束 |
| 适合终端 | Web、App | App、IoT、车机、设备、后台服务 |
| 系统复杂度来源 | 服务端业务架构 | Broker 治理与 Topic 设计 |
| 典型优势 | 前端接入简单、交互灵活 | 连接治理成熟、弱网友好、消息能力更强 |
哪些即时通讯场景更适合 WebSocket
1. Web 端聊天系统
比如:
- 企业内部 IM
- 在线客服
- 社区私信
- 直播间互动
- 协同编辑中的实时状态同步
原因很简单:
- 浏览器接入直接
- 前端实现成本低
- 自定义协议灵活
- 和现有登录态、网关体系容易集成
2. 高交互型实时产品
比如:
- 在线白板
- 协同文档
- 棋牌游戏
- 实时字幕
- 行情/看板/监控台
这些系统不只是“收消息”,而是有大量交互事件。 WebSocket 的自由协议模型会更舒服。
3. 业务逻辑很强、协议要高度自定义
例如你需要同时传:
- 聊天消息
- 光标位置
- 语音控制帧
- 输入状态
- UI 指令
- 房间控制指令
这种情况下,WebSocket 更像一条“业务总线”。
哪些即时通讯场景更适合 MQTT
1. 设备消息与人消息混合的系统
比如:
- 智能家居 App + 设备通知
- 工业监控 IM 告警
- 车联网终端消息系统
- 机器人/硬件终端协同平台
这类系统的通信对象不是纯人类用户,还包含:
- 传感器
- 网关设备
- 边缘节点
- 小程序 / App
- 后台控制台
MQTT 的 Topic 模型和弱网能力非常匹配。
2. 弱网和移动网络波动明显的场景
比如:
- 户外巡检
- 物流轨迹终端
- 远程医疗设备
- 海量 App Push 通道
MQTT 的轻量和重连模型更稳定。
3. 大规模连接接入平台
当你的系统重点不是“一个聊天功能”,而是“一个统一连接平台”时,MQTT 更有吸引力,例如:
- 百万级终端在线
- 多种终端协议统一接入
- 消息按主题分层路由
- 连接状态集中管理
为什么很多成熟系统最后都会选混合架构
实际工程里,很少有人只盯着协议本身做选择。 真正决定架构的,是终端结构和业务边界。
最常见的落地方案不是二选一,而是:
- 浏览器 / H5 / PC 客户端使用 WebSocket
- 移动端、设备端、边缘侧使用 MQTT
- 后端统一进入消息中台或事件总线做汇聚
也可能是:
- 前端接入层:WebSocket Gateway
- 设备接入层:MQTT Broker
- 业务层:消息服务、会话服务、路由服务、离线服务
- 存储层:消息库、会话库、索引库
- 分发层:Kafka / Redis Stream / Pulsar 等内部总线
一套更真实的 IM 混合架构应该怎么设计
架构分层
1. 接入层
负责维护客户端长连接。
- Web 客户端 → WebSocket Gateway
- App / Device → MQTT Broker 或 MQTT Gateway
2. 会话与身份层
负责:
- 鉴权
- 用户与设备身份统一
- 多端登录管理
- 在线状态维护
- 连接映射关系
3. 消息处理层
负责:
- 消息 ID 生成
- 消息校验
- 幂等去重
- 敏感词处理
- 消息落库
- 投递策略生成
4. 路由分发层
负责:
- 单聊路由
- 群聊扩散
- 广播消息
- 跨节点分发
- 在线 / 离线判断
5. 离线与同步层
负责:
- 未读消息
- 历史消息拉取
- 断线重连补偿
- 已读回执同步
- 多端消息同步
关键设计原则
1. 不要把协议能力误当成业务能力
很多团队一看到 MQTT 有 QoS,就以为聊天可靠性问题解决了。 这不成立。
即时通讯里的“可靠”至少包括:
- 服务端是否成功接收
- 接收端是否成功消费
- 是否需要送达回执
- 是否需要已读回执
- 重复消息如何去重
- 断线后如何补同步
- 多端如何保持一致
这些能力都需要业务层完成。 MQTT 只是把协议层可靠性基础做得更好,不等于业务层天然完整。
2. 不要把 WebSocket 当成“直接能做大规模 IM”
WebSocket 很容易做出演示版,但从单机 Demo 到生产级 IM 中间差着很多基础设施:
- 连接网关集群
- 用户路由表
- 跨节点投递
- 消息持久化
- 离线补偿
- ACK 与去重
- 心跳与重连治理
- 限流与熔断
真正难的从来不是“建立连接”,而是“连接后的系统治理”。
3. Topic 设计是 MQTT 成败关键
MQTT 项目后期最容易踩坑的就是 Topic 设计混乱。 常见问题有:
- 主题层级不统一
- 权限边界模糊
- 通配符订阅过大
- 群聊和私聊主题混用
- 多租户隔离不清楚
建议 Topic 设计一开始就明确:
- 业务域
- 租户
- 用户或设备身份
- 消息类型
- 读写权限边界
例如:
tenant/{tenantId}/im/user/{userId}/inboxtenant/{tenantId}/im/group/{groupId}/messagetenant/{tenantId}/presence/{userId}tenant/{tenantId}/device/{deviceId}/control
架构选型时最该看的,不是协议,而是这 6 个问题
1. 你的主客户端是谁
- 主要是浏览器:优先 WebSocket
- 主要是设备、App、嵌入式终端:优先 MQTT
2. 你的网络环境是否稳定
- 稳定公网 / 内网:WebSocket 足够
- 弱网、频繁掉线、移动切换:MQTT 更稳
3. 你更需要“自由协议”还是“成熟消息模型”
- 需要高度自定义:WebSocket
- 需要成熟 Pub/Sub:MQTT
4. 你的系统规模如何
- 中小规模、Web 聊天为主:WebSocket 更简洁
- 海量连接、终端接入平台:MQTT 更自然
5. 你是否有设备侧场景
- 没有:WebSocket 通常够用
- 有,而且比重不小:MQTT 往往更合理
6. 你团队擅长治理哪类复杂度
- 更擅长业务网关和应用服务开发:WebSocket
- 更擅长消息中间件、Broker、主题治理:MQTT
三类典型选型建议
方案一:纯 Web IM 系统
例如企业聊天、在线客服、社区私信。
推荐
WebSocket 为主
原因
- 浏览器接入成本最低
- 前后端联调简单
- 业务协议灵活
- 可快速支撑单聊、群聊、在线状态、输入状态、已读回执
补充要求
- 自定义 ACK
- 离线消息存储
- 重连补拉机制
- 分布式路由与跨节点转发
方案二:App + 设备 + 后台协同系统
例如智能家居、工业监控、车联网消息系统。
推荐
MQTT 为主
原因
- 多终端统一接入方便
- Topic 路由天然适合控制和通知
- 弱网和大规模连接表现更好
- Broker 更适合作为统一消息入口
补充要求
- 精细化 Topic 权限
- 会话模型与聊天语义补充
- 消息持久化与历史同步服务
方案三:大型综合即时通讯平台
例如既有 Web/App 聊天,又接设备消息、系统通知、机器人消息。
推荐
WebSocket + MQTT 混合架构
原因
- WebSocket 负责用户实时交互
- MQTT 负责设备、弱网终端、系统事件流
- 后台通过统一消息中台做聚合和编排
关键点
- 统一身份体系
- 统一消息 ID
- 统一离线存储
- 统一回执机制
- 协议层和业务层解耦
一个容易被忽略的问题:即时通讯并不只是一条长连接
很多架构讨论过于聚焦协议,忽略了 IM 真正复杂的部分。 协议选型只是起点,真正决定系统上限的是这些能力:
- 会话模型
- 消息存储模型
- 顺序语义
- 未读计数
- 多端同步
- 消息撤回
- 已读回执
- 漫游消息
- 敏感内容处理
- 分布式一致性与幂等
所以更准确地说:
- WebSocket 决定的是实时通道方式
- MQTT 决定的是终端接入和消息分发方式
- 真正的即时通讯能力,最终仍要靠业务架构补齐
最终建议
如果你面对的是一个标准的 Web 聊天或企业 IM 项目,直接选 WebSocket,通常是最符合工程现实的方案。 它不是能力最全的协议,但在浏览器生态、开发效率、业务灵活性上最均衡。
如果你面对的是一个多终端、弱网、海量连接、设备侧占比高的系统,优先选 MQTT。 它不是浏览器体验最好的协议,但在连接治理、轻量通信和消息路由上更专业。
如果你的系统既有人聊天,也有设备消息、系统通知、机器人事件流,别硬做二选一,直接上混合架构。 现实中的大系统,往往不是“选哪个协议”,而是“把哪个协议放在最合适的位置”。
协议没有绝对优劣,只有是否匹配你的终端结构、网络环境和系统复杂度。