1 MQTT介绍
MQTT是一种基于客户端/服务器架构(CS架构)的发布/订阅模式的消息传输协议。它最初由IBM开发,并被设计成为轻量、开放、简单以及易于实现的消息传输协议。MQTT很适合应用于环境受限(窄带、高延迟、不可靠的网络环境)的机器与机器(M2M)、物联网(IoT)设备之间的消息通信。
2 MQTT的RETAIN标志位
当我们使用MQTT客户端发布消息(PUBLISH
)时,如果将RETAIN标志位设置为true
,那么MQTT服务器会将最近收到的一条RETAIN标志位为true
的消息保存在服务器端(内存或文件)。
特别注意:MQTT服务器只会为每一个Topic保存最近收到的一条RETAIN标志位为true
的消息!也就是说,如果MQTT服务器上已经为某个Topic保存了一条Retained消息,当客户端再次发布一条新的Retained消息,那么服务器上原来的那条消息会被覆盖!
每当MQTT客户端连接到MQTT服务器并订阅了某个topic,如果该topic下有Retained消息,那么MQTT服务器会立即向客户端推送该条Retained消息。
2.1 发布RETAIN消息
如果想让MQTT服务器为某个Topic保留消息,只需要在发布消息的时候指定RETAIN标志位为true
即可。例如:1
2
3
4
5String topic = "retained/test";
byte[] payload = new byte[] {0x00, 0x01, 0x12};
int qos = 0;
boolen retained = true;
client.publish(topic, payload, qos, retained);
特别注意:消息的RETAIN标志位与消息的QoS无关,即无论使用哪种级别的QoS,只要设置了RETAIN标志位为true
,那么MQTT服务器就会保存该条消息!
2.2 删除RETAIN消息
如果客户端想让MQTT服务器删除某个Topic下保存的Retained消息,唯一的方法是向MQTT服务器发布一条RETAIN标志位为true
的空消息。
空消息即为发布消息(PUBLISH
)的时候,Payload中设置0个字节的内容。
删除了某个Topic下保存的Retained消息,如果客户端没有再发布Retained消息,则MQTT服务器上对于该Topic就没有了Retained消息。
下面为删除某个Topic下保存的Retained消息的例子:1
2
3
4
5String topic = "retained/test";
byte[] payload = new byte[0];
int qos = 0;
boolen retained = true;
client.publish(topic, payload, qos, retained);
2.3 RETAIN消息的应用场景举例
在实际应用中,我们可以利用RETAIN标志位来完成一些特定的需求。例如物联网应用中,通常我们会有硬件设备和移动APP的交互:
用户想通过APP来控制硬件设备,在打开APP的时候,APP需要及时知道设备的在线状态,只有设备在线用户才能通过APP去控制设备。
如果每个设备都对应有一个Topic,例如online/status/{devId}
,每当设备上线或者离线,服务器都会往该Topic发布一条设备连接状态的消息,并指定RETAIN为true
;每个APP对应地订阅online/status/{devId}
,那么每当APP启动并成功订阅online/status/{devId}
主题的时候,就会自动收到MQTT服务器推送的设备在线状态消息。这样一来用户就能及时知道该设备是否在线,能不能控制。
注明: 以上提到的{devId}
为每个设备相应的设备ID
——————–【参考文章】——————–