MQTT(Message Queuing Telemetry Transport)是一种轻量级
的、基于发布/订阅模式
的消息传输协议,广泛应用于物联网(IoT)领域
中的设备连接、传感器数据传输等场景。
MQTT协议使用TCP/IP协议栈作为底层传输协议,支持QoS(服务质量)级别定义、保留消息等特性。在MQTT中,有一个消息代理(Broker)中心,客户端通过连接到消息代理,实现发布消息和订阅消息,从而实现设备之间的通信和数据传输。
相对于HTTP协议,MQTT具有更小的消息头和更少的网络流量占用,适合于低带宽、不稳定网络环境下的设备数据传输场景。同时,MQTT也支持不同的平台和语言的开发,如Java、Python、C++、JavaScript等等,可以方便地进行二次开发和应用。
MQTT协议的优点包括:
轻量级:MQTT协议设计简单,消息头部分较小,具有较低的网络流量消耗和较小的内存占用,适用于低带宽和资源受限的设备。
低功耗:MQTT协议采用异步传输机制,客户端可以通过保持持久连接的方式降低网络建立和断开的消耗,从而减少设备能耗。
异步通信:MQTT采用发布/订阅模式,使设备可以实现异步通信,即设备可以推送消息到消息代理,而不需要立即等待接收方的响应,提高了系统的响应速度和吞吐量。
灵活的消息订阅机制:MQTT支持多级主题订阅,即通配符订阅,允许设备订阅特定主题或一组主题,从而更灵活地管理和控制消息的订阅。
可靠性和服务质量:MQTT协议支持三个不同的服务质量(QoS)级别,分别为至多一次、至少一次和正好一次,可以根据应用需求选择适当的级别,保证消息的可靠传输。
跨平台和语言支持:MQTT具有跨平台和跨语言的特性,允许在不同的硬件平台和编程语言中使用,并且有丰富的开发库和工具可供选择和使用。
综上所述,MQTT协议的轻量级、低功耗、异步通信、灵活订阅、可靠传输和跨平台支持等特点使其成为物联网设备连接和通信的理想选择。
MQTT协议支持使用通配符(wildcard)进行主题(Topic)的订阅和发布。通配符的使用可以让设备更灵活地管理和控制消息的订阅。
MQTT协议中有两种通配符:
单层通配符(Single-Level Wildcard):表示为"+"(加号)。可以用于任意层级的主题的一级通配,可以匹配单个层级的主题标识。例如,“home/+/light” 可以匹配 “home/kitchen/light” 和 “home/livingroom/light”,但不能匹配 “home/kitchen/table/light”。
多层通配符(Multi-Level Wildcard):表示为"#"(井号)。只能用于主题的最后一级,用于匹配多个或零个层级的主题标识。例如,“home/kitchen/#” 可以匹配 “home/kitchen/light”、“home/kitchen/table/light” 等。
使用通配符能够使设备更加灵活地定义订阅规则,可以根据实际需要选择适当的通配符来订阅特定的主题。这样可以简化设备间的通信和数据传输,在物联网中更加方便和高效地实现设备与设备之间的互联互通。
MQTT协议通信流程:
连接阶段:
1.1. 客户端通过TCP/IP协议与MQTT代理建立网络连接。
1.2. 客户端发送CONNECT报文给代理,携带客户端标识符、协议版本、保持连接设置等信息。
1.3. 代理验证客户端信息,返回CONNACK报文作为连接确认,指示连接是否建立成功。
心跳保持:
2.1. 已建立连接的客户端和代理之间周期性地交换PINGREQ和PINGRESP报文来保持心跳。
2.2. 客户端在一段时间内未收到PINGRESP报文时,可以认为连接断开,并进行相应的处理。
发布与订阅:
3.1. 客户端发送SUBSCRIBE报文给代理,指定要订阅的主题和对应的服务质量(QoS)级别。
3.2. 代理接收SUBSCRIBE报文,记录客户端的订阅信息,并发送SUBACK报文给客户端,确认订阅请求。
3.3. 客户端向代理发送PUBLISH报文,发布消息到指定主题。
3.4. 代理接收到PUBLISH报文后,根据订阅关系将消息转发给对应的客户端。
3.5. 客户端收到PUBLISH报文后,根据消息的QoS级别发送相应的确认报文(PUBACK、PUBREC、PUBREL、PUBCOMP)。
3.6. 客户端可以发送UNSUBSCRIBE报文给代理,取消订阅一个或多个主题。
关闭连接:
4.1. 客户端发送DISCONNECT报文给代理,主动关闭连接。
4.2. 代理接收到DISCONNECT报文,断开与该客户端的连接。
MQTT由固定报头,可变报头,有效载荷三部分组成。
![2023-11-15T14:59:07.png][4]
MQTT协议中的每个报文都包含一个固定报头(Fixed Header),固定报头中包含了一些固定的信息以标识报文的类型和控制参数。下面是MQTT协议固定报头的基本结构:
报文类型(Message Type):占据固定报头的高4位(即最高位的四个比特),用于表示报文的类型。可能的取值包括:
控制标志(Control Flags):占据固定报头的低4位(即最低位的四个比特),用于表示控制参数。不同报文类型的控制标志具有不同的含义,常见的标志包括:
剩余长度(Remaining Length):占据固定报头的字节2至5。它表示整个报文的剩余长度(不包括固定报头的长度)。使用可变长度编码(Variable Length Encoding)表示,允许长度范围从 0 到 268,435,455 字节。
通过固定报头,客户端和代理可以快速解析报文,确定报文的类型和相应的控制参数,进而有效地处理和分发报文。
需要注意的是,MQTT协议的固定报头结构是通用的,但报文具体的数据结构和长度取决于不同的报文类型。每个报文类型在固定报头后面还会包含各自特定的可变头部(Variable Header)和有效负载数据(Payload),这些部分的结构和长度也会根据具体的需求而变化。
MQTT协议中,除了固定报头外,每个报文还可能包含可变报头(Variable Header)。可变报头包含了一些特定于消息类型的字段,用于提供关于消息的更多信息。下面是MQTT协议中可变报头的一般结构:
CONNECT报文的可变报头包含以下字段:
PUBLISH报文的可变报头包含以下字段:
SUBSCRIBE报文的可变报头包含以下字段:
SUBACK报文的可变报头包含以下字段:
其他报文类型的可变报头也包含与其功能和语义相关的信息。可变报头的结构和字段取决于消息类型和特定协议版本的要求。通过可变报头,可以为每种类型的报文提供必要的信息,以便接收方能够正确解释和处理消息。
需要注意的是,可变报头并不是所有报文类型都有的,但对于那些具有可变报头的报文类型来说,可变报头是非常重要的部分,它提供了报文的关键信息,以便接收方理解和处理报文。
MQTT协议中,有效载荷(Payload)包含了报文的实际数据,其结构和内容取决于具体的报文类型和应用需求。以下是几种常见的MQTT报文类型以及它们可能包含的有效载荷:
CONNECT报文的有效载荷包含了客户端的连接请求信息,主要包括:
CONNACK报文的有效载荷包含了服务器对连接请求的确认信息,主要包括:
PUBLISH报文的有效载荷包含了实际发布的消息内容,其中包括:
SUBSCRIBE报文的有效载荷包含了订阅请求的信息,主要包括:
SUBACK报文的有效载荷包含了订阅确认的信息,主要包括:
UNSUBSCRIBE报文的有效载荷包含了取消订阅请求的信息,主要包括:
UNSUBACK报文的有效载荷通常为空,因为它只是一个简单的确认消息。
PUBACK、PUBREC、PUBREL、PUBCOMP报文的有效载荷通常为空,因为它们主要用于消息发布的确认。
PINGREQ和PINGRESP报文没有有效载荷,因为它们主要用于维持连接状态而不传输实际数据。
DISCONNECT报文的有效载荷通常为空,因为它主要用于终止连接。
需要注意的是,有效载荷的具体结构和内容将根据具体的需求和通信的上下文进行定义,同时也受到MQTT协议版本和服务质量等级(QoS)的影响。MQTT的灵活性允许有效载荷的内容可以是任意格式的数据,包括文本、二进制数据等。
总的来说,有效载荷是MQTT报文中传输实际数据的部分,它的结构和内容对于消息的生产者和消费者之间的通信至关重要。