当前位置: 首页 > news >正文

MQTT协议知识点总结

一、基础协议 

1、MQTT协议是基于TCP/IP协议的;

2、MQTT消息传输是基于TCP长连接的; 

二、MQTT协议和HTTP协议的异同

1、相同点:

 (1)均基于TCP传输协议;

 (2)都能通过网络进行数据的接收和发送;

 (3)每次通信完成后立即断开连接;

 (4)支持加密通信。 

2、不同点:

(1)MQTT采用发布/订阅模式,而HTTP采用请求/响应模式;

(2)MQTT发送的消息消息头很小,而HTTP发送的消息消息格式臃肿;

(3)MQTT有多个等级的消息可靠性,而HTTP主要基于TCP的可靠性。

三、MQTT的三大机制

mqtt协议成为物联网领域的首选通信协议,成为行业龙头老大,是由于其具有的以下优势

1、省电;2、省流;3、省事。

其中省事主要体现在其拥有的三大机制:

​​​​​1、送达机制;2、离线机制;3、心跳机制。

1. 送达机制

送达机制是指为保证消息送达,MQTT提供了3个消息级别,确保消息送达的可靠性:

(1)至多一次,QoS = 0,如果采用该级别的送达机制,接收端不会确认,发送端不会重试;

(2)至少一次,QoS =1 接收端要有确认,发送端没有收到确认,会重复发送;

(3)刚好一次,QoS = 2 保证每条消息只被接收1次。共有4个步骤:

a.发送者发送消息;消息代理服务器将消息推送给订阅者;

b.订阅者收到消息,将确认收到传达给消息代理服务器,再转交给发送者,发送者收到确认收到通知;

c.发送者发送释放给消息消息代理服务器,订阅者收到发送释放通知;

d.订阅者将发送完成传达给消息代理服务器,转交给发送者。

MQTT消息等级的指定和确立

既然MQTT有三种消息等级,它是如何确认采用哪种等级的呢:

1、不管是消息的发布者,还是订阅者均可指定消息等级(QoS); 

2、发布者指定了消息等级(QoS)的目标对象是MQTT消息代理服务器,不是订阅者;

3、订阅者指定的消息等级(QoS)和发布者指定的消息等级(QoS)不一致时,接收到的消息不一定是指定等级(QoS)的消息,是发布者的QoS和订阅者的QoS两者间的最小值。

可参照下图进行理解,发布者和订阅者指定的消息等级一个是为0,一个是2,取最小值,则消息的最终等级为0,即至多一次,不保证消息能被订阅者收到:

2.离线机制

MQTT 的离线机制使得设备在网络状况不佳或需要定期休眠省电的场景下,依然能确保重要的消息不丢失,并在重新上线后及时同步状态,大大提升了通信的可靠性。

这是一种“善后”或“通知”机制。

  • 是什么? 客户端在连接时,可以预先设定好一条“遗嘱消息”(包含主题和内容),并告知代理。

  • 如何工作?

    1. 意外断开触发:如果客户端非正常断开(如网络突然中断、掉电,而不是先发送 DISCONNECT 包正常断开),代理会立即发布这条预设的遗嘱消息。

    2. 用途:用于通知其他订阅了遗嘱主题的客户端:“我(离线客户端)刚刚异常下线了”。这在系统监控和状态告警中非常有用。

3.心跳机制

MQTT 的心跳机制,正式名称是 Keep Alive。其核心目的不是传输数据,而是检测连接是否存活

工作原理如下:

  1. 协商间隔:客户端在发起连接(CONNECT 报文)时,会携带一个 Keep Alive 参数(单位为秒)。这个值代表客户端承诺的最大静默时间

    例如,设置 Keep Alive = 60,意味着客户端保证在任何 60 秒的时间间隔内,至少会与服务器有一次通信。

  2. 客户端的责任

    如果在该时间间隔内,客户端没有发送任何其他报文(如 PUBLISHSUBSCRIBE),它必须主动向代理(Broker)发送一个特殊的 PINGREQ 报文,以示“我还活着”。
  3. 代理的责任

    • 代理收到 PINGREQ 后,必须立即回复一个 PINGRESP 报文进行应答。

    • 同时,代理也会启动自己的计时器。如果代理在 1.5 倍 的 Keep Alive 时间内,既没有收到任何报文,也没有收到 PINGREQ,它就会判定客户端连接已死(例如网络中断、客户端崩溃)。

    • 此时,代理会主动断开 TCP 连接,并触发该客户端的遗嘱消息

简单来说: 它是一套应用层的“健康检查”协议,通过“一问一答”(PINGREQ/PINGRESP)来确认双方都还在线。

前面提到,MQTT是基于TCP协议的,TCP协议本身有心跳机制,但事实上MQTT并没有采用TCP心跳机制,而是单独设计了一套专属的心跳机制,其原因是:

  1. 跨网络环境的可控性与灵活性
    • TCP Keepalive 是操作系统内核实现的,其时间间隔(通常是 2 小时)通常需要系统权限才能全局修改,对应用程序来说不够灵活。

    • MQTT 常用于移动网络、卫星链路等高延迟、不稳定的环境。2 小时的心跳间隔太长,无法及时检测到连接中断。MQTT 的 Keep Alive 允许应用程序根据当前网络状况动态调整(如设置为 30 秒、60 秒),可以更快地发现故障,从而及时重连或告警,提升了响应速度。

  2. 避免中间设备的干扰

    • 许多网络中间设备(如 NAT 路由器、防火墙)有一个重要的特性:会话超时

    • 为了节省资源,这些设备会维护一个“连接映射表”。如果一条 TCP 连接在特定时间内(比如 5 分钟)没有任何数据包传输,设备会认为这个连接已经失效,并主动删除其映射表项

    • 即使操作系统层的 TCP Keepalive 还在工作(2小时一次),它也无法阻止中端的 NAT/防火墙在几分钟后就把这个连接“掐掉”。结果就是:两端的操作系统认为连接还活着,但中间路径已经断了,实际通信无法进行。

    • MQTT 的应用层心跳(频率更高,如 1 分钟一次)保持了连接上有规律的数据传输,能够“欺骗”过这些中间设备,防止其因超时而断开连接。

  3. 与应用层状态紧密绑定

    • MQTT 的心跳超时(1.5 * Keep Alive)直接触发的是应用层的逻辑:断开连接、清理会话、发布遗嘱消息。这是一个明确的应用层事件

    • 而 TCP Keepalive 超时只是一个传输层的事件,它只会关闭 TCP 套接字。应用程序可能需要更复杂的逻辑来捕获这个事件并触发相应的 MQTT 层处理(如发布遗嘱)。MQTT 自己管理心跳,可以将网络状态和应用状态更直接、更可靠地绑定在一起。

  4. 节省资源(对于电池供电设备)

    • 这听起来有点反直觉,但应用层心跳其实更省电。虽然 TCP Keepalive 报文更小,但它的不可控性可能导致不必要的唤醒。

    • 对于需要深度休眠以省电的 IoT 设备,它可以主动设置一个较长的 MQTT Keep Alive 时间(如 24 小时),然后在大部分时间休眠,只在需要通信或发送 PINGREQ 前才唤醒。

    • 如果依赖 TCP Keepalive,设备可能不得不更频繁地被操作系统唤醒以处理内核级别的保活包,这不利于电池续航。应用层心跳让设备对自己的功耗有完全的控制权。

总之,MQTT 自建心跳机制不是为了重复造轮子,而是为了在复杂的现实网络环境中提供一种更高效、更灵活、更可靠的连接保活方案,这是单纯的 TCP Keepalive 无法胜任的。两者可以共存,但角色和目的完全不同。

http://www.dtcms.com/a/394321.html

相关文章:

  • C++ 类和对象·其一
  • TypeScript里的类型声明文件
  • 【LeetCode - 每日1题】设计电影租借系统
  • Java进阶教程,全面剖析Java多线程编程,线程安全,笔记12
  • DCC-GARCH模型与代码实现
  • 实验3掌握 Java 如何使用修饰符,方法中参数的传递,类的继承性以及类的多态性
  • 【本地持久化】功能-总结
  • 深入浅出现代FPU浮点乘法器设计
  • LinkedHashMap 访问顺序模式
  • 破解K个最近点问题的深度思考与通用解法
  • 链式结构的特性
  • 报表1-创建sql函数get_children_all
  • 9月20日 周六 农历七月廿九 哪些属相需要谨慎与调整?
  • godot实现tileMap地图
  • 【Unity+VSCode】NuGet包导入
  • QEMU虚拟机设置网卡模式为桥接,用xshell远程连接
  • Week 17: 深度学习补遗:Boosting和量子逻辑门
  • 【论文速递】2025年第13周(Mar-23-29)(Robotics/Embodied AI/LLM)
  • Webpack进阶配置
  • 【LeetCode 每日一题】3227. 字符串元音游戏
  • 【图像算法 - 26】使用 YOLOv12 实现路面坑洞智能识别:构建更安全的智慧交通系统
  • 009 Rust函数
  • IT疑难杂症诊疗室
  • 视频播放器下载推荐,PotPlayer‌,KMPlayer,MPC-HC,GOM Player‌VLC media player,MPV,
  • Day04 分治 递归 | 50. Pow(x, n)、22. 括号生成
  • (博主大回归)洛谷题目:P1986 元旦晚会 题解 (本题简)
  • Windows Docker 环境下 VLLM 大模型存储最优解:Docker-Desktop 实例目录与多容器协同挂载方案
  • Elasticsearch面试精讲 Day 20:集群监控与性能评估
  • 如何解决 pip install 安装报错 ModuleNotFoundError: No module named ‘pydantic’ 问题
  • 设置永不待机 系统语言