0%

MQTT协议中部分特殊设置

MQTT协议基础(6):MQTT协议中部分特殊设置

MQTT协议中部分特殊设置Retained消息、LWT机制、Keepalive机制、连接保活等

Retained消息

作用

在发布订阅模式下,如果订阅者订阅的时间刚好在发布者发布消息之后,那么订阅者就必须等待下一条消息,在这段时间内,订阅者处于信息真空时期。

为了避免这一现象,提出了Retained消息的概念。其具有如下的特点

1.一个Topic只能有一条Retained消息,新的Retained会覆盖旧的Retained消息

2.如果订阅者采用通配符订阅主题,那他会收到所有匹配主题的Retained消息

3.只有新的订阅者才会收到Retained消息,如果一个订阅者重复订阅一个主题,那么在每次订阅时都会被当做新的订阅者,然后收到Retained消息

具体设计

操作方法就是在PUBLISH数据包上将Retained标识置1,Broker收到这个消息后将为该主题保存这个消息,当一个新的订阅者订阅该主题时,Broker会马上把这个消息发送给订阅者。

另:当Retained消息发送到订阅者时,PUBLISH数据包中Retain标识仍为1,这样订阅者就能判断是否为Retained消息,做出相应处理。

如果想删除某个主题的Retained消息,只需要向这个主题发布一个Payload为空的Retained消息即可。

LWT(Last Will and Testament)

包括遗愿主题,遗愿QoS,遗愿消息等。所谓遗愿是指Broker检测到Client非正常地断开连接时,向遗愿主题发布一条消息。其相关的设置是在CONNECT数据包中指定的。

  • Will Flag 是否使用LWT
  • Will Topic 遗愿主题,注意不可以使用通配符
  • Will Q is 发布遗愿消息时的QoS等级
  • Will Retain 遗愿消息的Retain标识
  • Will Message 遗愿消息内容

Broker在以下情况下会认为Client是非正常断开连接的

  • Broker检测到底层I/O异常
  • Client未能在Keepalive的时间间隔内和Broker之间进行消息交互
  • Client在关闭底层TCP连接前没有发送DISCONNECT数据包
  • Broker因为协议错误关闭了和Client的连接,比如Client发送了一个格式错误的MQTT协议数据包

如果Client通过发布DISCONNECT数据包断开连接,这属于正常断开连接,不会触发LWT机制。

Keepalive机制

MQTT协议是建立在TCP协议之上的应用层协议,当TCP协议断开时会通知上层应用层协议,但TCP协议存在一个半打开连接状态,这是非常不利的,会导致其中一端误以为连接依然存在。造成资源浪费。

为快速得知连接状态,设计Keepalive机制,在建立连接时设置Keepalive参数,MQTT协议规定在1.5个Keepalive时间间隔中如果没有信息交互,会认为彼此之间已经断开连接。

MQTT协议中设计一对PINGREQ/PINGRESP数据包来满足Keepalive的约定和连接状态的检测。


Keepalive机制的其它特性

  • 如果在一个时间间隔内已经有了消息交互,那就没必要发送心跳包了
  • Keepalive的值是有Client来指定的,不同Client可以指定不同的值
  • Keepalive的最大值为18小时12分15秒
  • Keepalive的值如果设置为0,代表不使用Keepalive 机制。

连接保活

  • 一般Client的连接保活
    这种情况下,直接在检测到断开连接之后,重新发起连接即可

  • 移动端的连接保活
    移动端最大的问题在于,当手机软件切入后台之后如何保活?

    • iOS客户端的方案
      借助苹果的APNs发送推送消息。具体流程如下
      当iOS系统中的APP被切入后台,接收MQTT协议消息的方式是

      1
      2
      3
      4
      5
      1.Publisher发布一条或多条消息
      2.Publisher通过某种途径告知APP的应用服务器,然后服务器通过苹果的APNs向对应的iOS订阅者推送一条消息
      3.用户点击推送,APP进入前台
      4.APP重新建立和Broker的连接
      5.APP收到Publisher刚刚发送的消息
    • Android客户端的方案
      一方面可以采用类似上述的推送机制,比如华为推送,小米推送。
      同时,也可以利用Android后台运行Service代码,在Service中创建和保持MQTT协议连接。