1. Client id
Connect报文必须的信息,broker用来区分不同的客户端。作为客户端可以不提供(clean session必须为true),broker会随机分配一个给它。
2. 服务质量Qos
1) QoS=0
消息只发一次,不需要确认,发送完之后,消息就会被broker删除。
2) QoS=1
消息至少发一次,需要确认。一旦确认,消息会被删除,没有确认,则会发送DUP=1的消息副本。broker分发消息的时候,不会去关注DUP的标志位,因此订阅者可能会收到重复的信息。
3)QoS=2,最慢的方法,需要4条消息。
消息至多发一次,需要
3. 遗愿
遗嘱消息是是在发布者异常断开时发送给订阅者的消息。通信过程中,如果遇到异常或者客户端心跳超时,MQTT服务器会替客户端发一个will消息,主要用于设备掉线后需要通知客户的场景。如果是客户端主动断开,则不会发will消息
4. 心跳
没有业务数据,也需要定时发送心跳消息,来确保连接不会断开。客户端发PINGQEQ,服务器端回复PINGRESP。一般情况下,如果1.5个心跳间隔周期还没收到客户端的消息,服务器就会断开于客户端的链接。最大可设置18h,也可以设置为0,0表示不断开
5. 清理会话
当一个客户端连接broker时,可以选择清理会话或者不清理会话。如果清理,则表示客户端只发布消息,broker不会存任何订阅信息或者没发送的消息。如果不清理,则表示会保存这些信息,要注意的是,哪些消息会被保存会收到订阅者和发布者的QOS等级的影响。
实际情况如下:
1) clean session = true,订阅者和发布者qos=0,订阅者reconnect的时候不会收到消息
2) clean session = false,订阅者和发布者qos=0,订阅者reconnect的时候不会收到消息。所以如果希望订阅者再掉线上线后,可以收到掉线期间的数据,就需要设置QOS=1+。不过当前设置,可以保证订阅者重新上线后,不需要重新订阅,因为broker会保存它的订阅信息
3) clean session = true,订阅者和发布者qos=1,订阅者reconnect的时候不会收到消息
4) clean session = false,订阅者和发布者qos=1,订阅者reconnect的时候会收到消息。也就是说,订阅者掉线后,发布者发送了某个消息,订阅者会在重新上线后收到该条消息
5) clean session = false,订阅者qos=1,发布者qos=0,订阅者reconnect的时候不会收到消息。
另外,消息一旦被订阅者确认,无论clean session和qos设置成什么,该条消息都会被立即删掉。
6. 保留消息
如果发布者发布了一条没有订阅者的消息,该条消息会立即被丢弃,在某些场景下,不希望这么做,就可以把保留消息标志位设置为1。比如某些只发一次但是又希望被之后出现的订阅者收到的消息。每一个topic只有一条保留消息。QOS对保留消息没有任何影响。
一旦设置了保留消息,后面再去发布非保留的消息,该条保留消息也不会被删掉。可以采用的方法是:重新发布一个保留标志位设置为1的空消息
7. 主题
MQTT的topic采用和文件夹一样的模式,通过斜杠/去分隔层级。
Topic要点:
1)大小写敏感;
2)使用UTF-8;
3)至少一个有效字符
除了$SYS之外,broker不会创建任何默认的主题。所有的主题都是由发布者或者订阅者创建的,并且这些主题不是永久的。只有当有客户端订阅某个主题,或者broker中有保留的消息或者遗嘱消息时,主题才存在。在出现订阅者或者发布者发布了保留位设置为1的消息时,主题会被自动创建。在最后一个该主题的订阅者断开连接且clean session为ture,或者一个客户端设置clean session为true去连接broker时,该状态
$SYS是一个保留的主题,一般用作broker发布一些broker相关的信息,客户端间不能用来交换消息。
客户端可以订阅一个或多个主题,这时候会用到通配符。# 表示多层级匹配,+ 表示单层级匹配。实际topic分析,以element的Topic为例:
1)bedroom/bulb1/set
订阅bulb1的设置消息
2)bedroom/bulb1/#
订阅bulb1全部消息,可能包括set,status等
3)element/+/set
订阅所有bulb的设置消息
客户端发布消息时,只能发布到唯一的主题中,不能使用通配符。
设计主题的一般思路:
1) 主题名最好对应一个设备或者是一小组设备;
2) 控制命令和数据最好是使用不同的主题名。E.g. element中的update和status;
3) 消息中的数据最好可以区分设备;
4) 在消息中的数据,一个设备的多个不同属性最好设计成JSON形式