原创

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 的典型特点

  1. 浏览器支持非常成熟

    • 前端可直接使用 WebSocket API
    • 不需要额外插件或复杂协议栈
  2. 协议层约束少

    • 传什么格式都行:JSON、Protobuf、二进制都可以
    • 非常适合业务自定义协议
  3. 开发自由度高

    • 聊天消息、心跳、在线状态、ACK、房间订阅,都可以自己定义
  4. 协议本身不解决消息可靠性

    • 是否确认送达
    • 是否支持重发
    • 是否有 QoS
    • 是否断线续传 这些都不是 WebSocket 原生解决的,需要业务层自己实现

这意味着什么

WebSocket 适合做“实时交互”,但它只是提供了一条实时通道。 通道之上的消息语义、可靠性和分发规则,需要你自己设计。


MQTT 的本质:一个带发布订阅语义的轻量消息协议

MQTT 最初就是为低带宽、不稳定网络和远程设备通信设计的。 它不是简单的“长连接协议”,而是一套完整的消息发布/订阅协议

MQTT 有几个核心角色:

  • Client:客户端,既可以发布消息,也可以订阅主题
  • Broker:消息代理,负责接收、路由、分发消息
  • Topic:主题,用来组织消息路由路径

比如:

  • 用户 A 发消息到 chat/private/user_1001
  • 用户 B 订阅 chat/private/user_1001
  • Broker 负责把消息投递给对应订阅者

MQTT 的典型特点

  1. 天然发布/订阅模型

    • 路由模型成熟,不必自己发明“频道、房间、订阅机制”
  2. 为弱网环境优化

    • 报文头小
    • 带宽占用低
    • 保活机制明确
  3. 支持 QoS

    • QoS 0:最多一次
    • QoS 1:至少一次
    • QoS 2:仅一次
  4. 支持保留消息、遗嘱消息、会话持续

    • 很适合在线状态同步、离线状态通知、设备上下线感知
  5. 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": "你好"
  }
}

然后还要再定义:

  • ack
  • heartbeat
  • typing
  • read_receipt
  • join_room
  • leave_room

MQTT

MQTT 的消息模型天然就是:

  • 发布到某个主题
  • 订阅某个主题
  • Broker 负责转发

你只要设计好 Topic 体系,例如:

  • im/user/1001/inbox
  • im/group/2001/messages
  • im/presence/1001
  • im/system/notice

判断

  • 业务协议高度定制、灵活性优先:WebSocket 更自由
  • 消息路由和订阅关系复杂:MQTT 更省事

3. 消息可靠性

这是两者差异最大的点之一。

WebSocket

WebSocket 本身不保证业务消息一定送达。 TCP 能保证字节流传输,但不能替你解决这些业务问题:

  • 客户端收到了没有
  • 客户端处理成功没有
  • 断线期间漏掉的消息怎么办
  • 服务端重发后如何去重
  • 多端登录如何协调回执状态

所以基于 WebSocket 做 IM,通常都要自己实现:

  • 业务消息 ID
  • 服务器 ACK
  • 客户端 ACK
  • 重试机制
  • 去重机制
  • 离线补拉

MQTT

MQTT 原生支持 QoS:

  • QoS 0:不保证到达,性能最高
  • QoS 1:至少一次,可能重复
  • QoS 2:仅一次,最重

看起来 MQTT 完胜,但要注意两个现实问题:

  1. QoS 不是“聊天业务可靠性”的全部

    • 它解决的是协议层投递语义
    • 不是已读、送达、会话一致性、历史同步这些完整业务语义
  2. 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}/inbox
  • tenant/{tenantId}/im/group/{groupId}/message
  • tenant/{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。 它不是浏览器体验最好的协议,但在连接治理、轻量通信和消息路由上更专业。

如果你的系统既有人聊天,也有设备消息、系统通知、机器人事件流,别硬做二选一,直接上混合架构。 现实中的大系统,往往不是“选哪个协议”,而是“把哪个协议放在最合适的位置”。

协议没有绝对优劣,只有是否匹配你的终端结构、网络环境和系统复杂度。

正文到此结束
评论插件初始化中...
Loading...