文章目录
QOS
什么是Qos
Qos:Quality of Service,服务质量。设置不同的等级可以确保某些重要信息准确传输到接收端。
Qos级别
- Qos = 0:最多发一次
- Qos = 1:最少发一次
- Qos = 2:保证收一次
Qos = 0
Qos的最低级别, 最多发一次,无论接收端是否接收消息。该级别不能保证所有信息都能得以传输,接收端能不能接收到信息与网络的稳定情况有关,完全依赖于TCP重传机制。
Qos = 1
最少发送一次,发送端在发送完信息后会检查接收端是否接到信息
消息传输情况
假如一段时间内,发送端没有接收到PUBACK报文,则发送端会再次发送消息,然后等待接收端的PUBACK报文。
所以当Qos = 1时,每条消息至少会传送一次。当发送端重复发送同一条消息时,会将PUBLISH中的dup设置为true。
MQTT 客户端在接收到消息之后,可以去判断 dup 标志以确定此消息是否为重复消息,应用程序应该对此作出相应的处理
注意:Qos=1 时,MQTT 服务器是不会进行去重的,只要发布者或者服务器没有收到 PUBACK 报文,
就认为主题消息没有发送成功进入重发;服务器或者订阅者,不会根据 dup 标志的值进行去重(也就是说
协议本身不会去重),需要我们的客户端应用程序去进行判断、处理。
Qso = 2
保证接收一次,MQTT 协议可以确保接收端只接收一次消息。
在 QoS=1 的情况下,接收端接收到消息的次数可能不止一次:>=1
消息传输情况
- 发送端向接收端发送 PUBLISH 报文
- 接收端接收到 PUBLISH 报文后,向发送端回复一个 PUBREC 报文(官方称其为–发布收到)
- 发送端接收到 PUBREC 报文后,会再次向接收端发送 PUBREL 报文(官方称其为–发布释放)
- 接收端接收到 PUBREL 报文后,会再次向发送端回复一个 PUBCOMP 报文(官方称其为–发布完
成)
如果发送端接收到 PUBCOMP 报文表示消息传输成功,它确认接收端已经成功接收到消息,整个过
程结束
保留消息
通过PUBLISH报文中的retain标志设置,是一个bool值,
作用
可以使订阅了带有保留消息主题的客户端上线后就能接收到主题信息。
例如,假设主题的发布者在整点(例如7:00)时会向服务器发送室温。
当7:15的时候有一个订阅了该主题的客户端上线了。
1、主题发布者没有设置保留消息,则新上线的客户端是没有办法接收到7点时的室温温度的,只能等到8:00时才能接收到室温
2、主题发布者设置保留消息,则新上线的客户端,上线后能接收到7:00时的室温信息的。
更新保留消息
每一个主题只能有一个“保留消息”,如果客户端想要更新“保留消息”,就需要向该主题发送一条新的“保留消息”,这样服务端会将新的“保留消息”覆盖旧的“保留消息”。当有客户端订阅该主题时,服务端就会将最新的“保留消息”发送给订阅者。
删除保留消息
要向该主题发布一条空的“保留消息”。
心跳机制
通过keepAlive设置
用来保持和服务器的链接,有些客户端只是消息的订阅者或者是不经常向服务器发布主题,这时就需要心跳机制来保持与服务器的链接了。
心跳机制原理
让客户端在没有向服务端发送消息的这个空闲时间里,定时向服务端发送一个心跳包,这个心跳包被称为心跳请求,其实质就是向服务端发送一个 PINGREQ 报文;当服务端收到PINGREQ 报文后就知道该客户端依然在线,然后向客户端回复一个 PINGRESP 报文,称为心跳响应
消息传输情况
心跳是定时发送的,服务器知道客户端每个多少秒会向服务器发送心跳,服务器一旦未收到客户端的心跳包,就知道客户端可能断线了。
客户端可以通过心跳包判断自己与服务器是否断开链接。
遗嘱机制
客户端与服务器断开链接的两种方式
- 客户端主动向服务端发送 DISCONNECT 报文,请求断开连接,自然服务端也就知道了客户端要离线了;
- 客户端意外掉线。被动与服务端断开了连接。
遗嘱机制是在意外掉线是使用的。一旦客户端意外断线,服务端就可以将客户端的遗嘱公之于众。
设置遗嘱
遗嘱消息和普通 MQTT 消息很相似,也有主题和正文内容
在客户端连接服务端时的CONNECT报文中设置。CONNECT报文如下:
willTopic – 遗嘱主题
告知服务端,本客户端的遗嘱主题是什么。只有那些订阅了这一遗嘱主题的客户端才会收到本客户端的遗嘱消息。
willMessage – 遗嘱消息
遗嘱的内容。
willRetain – 遗嘱消息的保留标志
遗嘱消息也可以设置为保留标志,用于告诉服务端是否需要对遗嘱消息进行保留处理
willQoS – 遗嘱消息的 QoS
这里的服务质量与普通MQTT 消息的服务质量是一样的概念
用户密码认证
同样存在于CONNECT报文中
上图中红框所示的两个参数:username(用户名)和 password(密码),这里的用户名和密码是客户端连接服务端时进行认证所需要的。