MQTT通信协议使用说明
目录
- 1 MQTT连接属性
- 1.1 服务器URL(Broker Address)
- 1.2 客户端标识(clientID)
- 1.3 用户名称 & 密码(User Name & Password)
- 1.4 连接超时(Connection Timerout)
- 1.5 心跳间隔 (KeepAlivelnterval)
- 1.6 清除会话(cleanSession)
- 2 主题&消息
- 2.1 主题
- 2.1.1 订阅主题(SUBSCRIBE)
- 2.1.2 订阅确认(SUBACK)
- 2.1.3 取消订阅(UNSUBSCRIBE)
- 2.2 消息
- 2.2.1 主题名(topicName)
- 2.2.2 服务质量等级(QoS)
- 2.2.3 报文标识符(packetID)
- 2.2.4 保留标志(retainFlag)
- 2.2.5 有效载荷(Payload)
- 2.2.6 重发标志(dupFlag)
- 3 MQTT遗嘱
- 3.1 遗嘱主题(Last Will Topic)
- 3.2 遗嘱消息(Last Will Message)
- 3.3 遗嘱Qos (Last Will Qos)
- 3.4 遗嘱保留 (Last Will Retain)
- 4 服务质量等级(QoS)
- 4.1 QoS = 0(最多发一次)
- 4.2 QoS = 1(最少发一次)
- 4.3 QoS = 2(保证收一次)
- 5 保留消息(retainFlag)
- 6 心跳间隔 (KeepAlivelnterval)
- 参考资料
以下所有内容,并非本博第一手编写资料,大部分内容来自于太极创客官网。详细内容请移步太极创客官网链接。
1 MQTT连接属性
1.1 服务器URL(Broker Address)
云端服务器地址
例:test.ranye-iot.net 或 47.92.129.18
1.2 客户端标识(clientID)
client
:n. 客户,委托人,客户机。
MQTT 服务端用该标识来识别客户端,因此标识名称必须是独立且唯一的。
1.3 用户名称 & 密码(User Name & Password)
针对申请的专用服务器,需要在访问服务器时验证用户名和密码。
而对于开方的服务器则可以缺省该选项。
1.4 连接超时(Connection Timerout)
连接超时和等待超时,一般用于设定连接时的等待时间。
1.5 心跳间隔 (KeepAlivelnterval)
服务器根据设置的时间间隔检查客户端是否保持连接情况。
1.6 清除会话(cleanSession)
为了保证重要的MQTT报文可以被客户端准确无误的接收到。在服务端想客户端发送报文后,客户端会向服务端返回一个确认报文。
如果服务端没有收到客户端的确认报文,服务端会认为刚刚发送的报文没有送达给客户端。这种情况下,服务端将会将尚未被客户端确认的报文保存起来,再次尝试向客户端发送报文,并且再次等待客户端发来的确认消息。
注:该选项可以设置为True
或 False
。
True
:服务端不需要确认收到的报文。
False
:服务端需要确认收到的报文。
(不要置一,这块没写反)
2 主题&消息
2.1 主题
所有MQTT消息都有主题。客户端要想接收消息,首先要订阅该消息的主题。当有客户端向该主题发布消息后,订阅了该主题的客户端就能接收到消息了。
2.1.1 订阅主题(SUBSCRIBE)
客户端想要订阅主题,需要向客户端发送 SUBSCRIBE
报文实现订阅主题请求,一个 SUBSCRIBE
报文可以用于订阅一个或多个主题。
同样的,客户端在订阅主题时也可以明确QoS。服务端会根据SUBSCRIBE中的QoS来提供相应的服务保证。
另外每一个SUBSCRIBE报文还包含有“报文标识符”。报文标识符可用于对MQTT报文进行标识。不同的MQTT报文所拥有的标识符不同。MQTT设备可以通过该标识符对MQTT报文进行甄别和管理。
订阅返回码详细列表:
返回码 | 说明 |
---|---|
0 | 订阅成功-QoS 0 |
1 | 订阅成功-QoS 1 |
2 | 订阅成功-QoS 2 |
128 | 订阅失败 |
2.1.2 订阅确认(SUBACK)
服务端接收到客户端的订阅报文后,会向客户端发送SUBACK报文确认订阅。
SUBACK报文包含有“订阅返回码”和“报文标识符”这两个信息。
2.1.3 取消订阅(UNSUBSCRIBE)
UNSUBSCRIBE
报文包含两个重要信息,第一个是取消订阅的主题名称。同一个 UNSUBSCRIBE
报文可以同时包含多个取消订阅的主题名称。另外,UNSUBSCRIBE
报文也包含“报文标识符”,MQTT设备可以通过该标识符对报文进行管理。
当服务端接收到UNSUBSCRIBE
报文后,会向客户端发送取消订阅确认报文—— UNSUBACK
报文。该报文含有客户端所发送的“取消订阅报文标识符”。
2.2 消息
MQTT一旦连接服务器便可以发布消息,发布的每条消息必须包含一个主题。服务器可以通过主题确定将消息转发给那些客户端。
MQTT客户端发布消息时,会向服务端发送PUBLISH报文。以下是报文的详细内容
2.2.1 主题名(topicName)
主题名用于识别此信息发布到哪一个主题。
2.2.2 服务质量等级(QoS)
QoS(Quality of Service) 表示MQTT消息的服务质量等级。三个等级:0
,1
,2
2.2.3 报文标识符(packetID)
设备可以通过报文标识符对MQTT报文进行甄别和管理。
注:报文标识符的内容与QoS级别关联。只有QoS级别大于0
时,报文标识符才是非零数值。
如果QoS级别等于0
时,报文标识为 0。
2.2.4 保留标志(retainFlag)
默认情况下,当客户端订阅了某一主题后,并不会马上接收到该主题的信息。只有在客户端订阅该主题后,服务端接收到该主题的新信息时,服务端才会将新消息推送给订阅该主题的客户端。
假如客户端在订阅该主题后,需要马上接收到该主题的第一条消息,这时候就需要用到保留标志这一信息。
2.2.5 有效载荷(Payload)
有效载荷是我们希望通过MQTT实际发送的内容。使用MQTT协议发送的文本,图像等格式的内容都是通过有效载荷发送的。
2.2.6 重发标志(dupFlag)
当MQTT报文的接收方没有及时确认收到报文时,发送方会重复发送MQTT报文。在重复发送MQTT报文时,发送方会将此“重发标志”设置为true。请注意,重发标志只在QoS级别大于0时使用。
3 MQTT遗嘱
为了让客户端可以更好的发挥作用,便于服务端管理。MQTT协议允许客户端在活着(保持连接)的时候就写好遗嘱。当客户端意外断线(正常断开连接不属于意外)时,服务端就可以将客户端的遗嘱公之于众。
3.1 遗嘱主题(Last Will Topic)
只有订阅了遗嘱主题的客户端才会收到本客户端的遗嘱消息。
3.2 遗嘱消息(Last Will Message)
定义遗嘱消息的内容
3.3 遗嘱Qos (Last Will Qos)
遗嘱消息的服务质量,可以设置0
、1
、2
的服务质量级别,服务端会使用不同的服务质量来发布遗嘱消息。
3.4 遗嘱保留 (Last Will Retain)
遗嘱消息可以设置为保留消息。
4 服务质量等级(QoS)
上文中多次提到QoS,MQTT服务质量(Quality of Service 缩写 QoS)正是用于告知物联网系统,哪些信息是重要信息需要准确无误的传输,而哪些信息不那么重要,即使丢失也没有问题。
MQTT协议有三种服务质量级别;
4.1 QoS = 0(最多发一次)
0是服务质量QoS的最低级别。QoS=0的情况下,MQTT服务端和客户端不会对消息传输是否成功进行确认和检查。消息能否成功传输全看网络环境是否稳定。
在网络环境稳定的情况下,信息传输一般是不会出现问题的。但是在环境不稳定的情况下,可能会在传输过程中出现MQTT消息丢失的情况。
4.2 QoS = 1(最少发一次)
当QoS级别为1时,发送端在消息发送完成后,会检查接收端是否已经成功接收到了消息。
发送端将消息发送给接收端后,会等待接收端的确认。接收端成功接收消息后,会发送一条确认报文PUBACK给发送端。如果发送端收到了这条PUBACK确认报文,那么它就知道消息已经成功接收。
假如过了一段时间后,发送端没有收到PUBACK报文,那么发送端会再次发送消息,然后再次等待接收端的PUBACK确认报文。因此,当QoS=1时,发送端在没有收到接收端的PUBACK确认报文以前,会重复发送同一条消息。
当发送端重复发送一条消息时,PUBLISH报文中的dupFlag
会被设置为True
(如上图黑色横线所标注的部分)。这是为了告诉接收端,此消息为重复发送的消息。
4.3 QoS = 2(保证收一次)
MQTT服务质量最高级是2级,即QoS = 2。当MQTT服务质量为2级时,MQTT协议可以确保接收端只接收一次消息。
收发流程:
1、发送端发送QoS=2 的PUBLISH
的报文给接收端;
2、接收端回复PUBLISH
的确认报文;
3、发送端收到PUBREC
报文后,会把此报文进行存储;
4、发送端应答PUBREL
报文给接收端;
5、接收端应答PUBCOMP
报文给发送端;
5 保留消息(retainFlag)
假设客户端1每次整点会发布一个主题的消息给服务端,客户端2订阅接收该主题的消息。如果客户端2在08:01
时刻上电启动,那么再未来的59分钟内,都处于无消息可处理的空闲状态。
为了避免这种情况,将保留消息(retainFlag)设置为Ture,无论客户端2何时上电工作,都会马上收到该主题中的“保留消息”。
6 心跳间隔 (KeepAlivelnterval)
客户端在心跳间隔时间内,如果有消息发布,那就直接发布消息而不发布心跳请求,但是在心跳间隔时间内,客户端没有消息发布,那么它就会发布一条心跳请求给服务端,这个心跳请求的目的就是为了告诉服务端,我还在线,你放心吧。
另外,在实际运行中,如果服务端没有在1.5倍心跳时间间隔内收到客户端发布消息(PUBLISH)或发来心跳请求(PINGREQ),那么服务端就会认为这个客户端已经掉线。
最后,心跳机制不仅仅用于服务端判断客户端是否在线。客户端也可以利用这一机制来判断自己是否与服务端仍保持连接。如果客户端发送了心跳请求(PINGREQ)给服务端一段时间后,仍然没有收到服务端回复的心跳确认。那么客户端也会认为自己已经断开了与服务端的连接。
参考资料
- 太极创客http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-tuttorial/mqtt-tutorial/mqtt-last-will/