图片100
MQTT(Message Queuing Telemetry Transport,消息队列传输)是在ISO标准(ISO/IECPRF20922)下基于发布/订阅模式的消息协议。该协议适用于TCP/IP协议,是一种发布/订阅型消息协议,适用于硬件性能较差的远程设备和网络状况较差的情况。
MQTT协议的实现需要完成客户端与服务器端的通信,在MQTT协议中,MQTT具有三种身份:发行者(Publish)、代理(服务器)、订户(Subscribe)。在这两种情况下,消息的发行者和订户是客户端,消息代理是服务器。
客户机作为使用MQTT协议的应用程序或设备,始终与服务器建立网络连接,并可以:
(1)发布信息,其他客户可以订阅。
(2)订阅其他客户机发出的邮件。
(3)退订或删除申请的邮件。
(4)从服务器断开。
MQTT服务器也称为“消息代理”(Broker),位于消息发布程序和订户之间,可以:
(1)从客户那里接受联网;
(2)接受由顾客提供的申请资料;
(3)处理客户提出的订户和退订要求;
(4)将应用程序消息转发给订阅客户。
MQTT协议中核心概念。
1)Sender 向 Receiver 发送一个带有消息数据的 PUBLISH 包, 并在本地保存这个 PUBLISH 包。
2)Receiver 收到 PUBLISH 包以后,向 Sender 发送一个 PUBACK 数据包,PUBACK 数据包没有消息体(Payload),在可变头中(Variable header)中有一个包标识(Packet Identifier),和它收到的 PUBLISH 包中的 Packet Identifier 一致。
3)Sender 收到 PUBACK 之后,根据 PUBACK 包中的 Packet Identifier 找到本地保存的 PUBLISH 包,然后丢弃掉,一次消息的发送完成。
4)如果 Sender 在一段时间内没有收到 PUBLISH 包对应的 PUBACK,它将该 PUBLISH 包的 DUP 标识设为 1(代表是重新发送的 PUBLISH 包),然后重新发送该 PUBLISH 包。重复这个流程,直到收到 PUBACK,然后执行第 3 步。
QoS 2:Sender 发送的一条消息,Receiver 确保能收到而且只收到一次,也就是说 Sender 尽力向 Receiver 发送消息,如果发送失败,会继续重试,直到 Receiver 收到消息为止,同时保证 Receiver 不会因为消息重传而收到重复的消息。
QoS 2 使用 2 套请求/应答流程(一个 4 段的握手)来确保 Receiver 收到来自 Sender 的消息,且不重复:
1)Sender 发送 QoS 为 2 的 PUBLISH 数据包,数据包 Packet Identifier 为 P,并在本地保存该 PUBLISH 包;
2)Receiver 收到 PUBLISH 数据包以后,在本地保存 PUBLISH 包的 Packet Identifier P,并回复 Sender 一个 PUBREC 数据包,PUBREC 数据包可变头中的 Packet Identifier 为 P,没有消息体(Payload);
3)当 Sender 收到 PUBREC,它就可以安全地丢弃掉初始的 Packet Identifier 为 P 的 PUBLISH 数据包,同时保存该 PUBREC 数据包,同时回复 Receiver 一个 PUBREL 数据包,PUBREL 数据包可变头中的 Packet Identifier 为 P,没有消息体;如果 Sender 在一定时间内没有收到 PUBREC,它会把 PUBLISH 包的 DUP 标识设为 1,重新发送该 PUBLISH 数据包(Payload);
4)当 Receiver 收到 PUBREL 数据包,它可以丢弃掉保存的 PUBLISH 包的 Packet Identifier P,并回复 Sender 一个 PUBCOMP 数据包,PUBCOMP 数据包可变头中的 Packet Identifier 为 P,没有消息体(Payload);
5)当 Sender 收到 PUBCOMP 包,那么它认为数据包传输已完成,它会丢弃掉对应的 PUBREC 包。如果 Sender 在一定时间内没有收到 PUBCOMP 包,它会重新发送 PUBREL 数据包。
我们可以看到在 QoS2 中,完成一次消息的传递,Sender 和 Reciever 之间至少要发送四个数据包,QoS2 是最安全也是最慢的一种 QoS 等级了。
1)Sender将PUBLISH包和Receiver发送到Receiver,并将此PUBLISH包保存在本地。
2)Receiver接收到PUBLISH包后,将PUBACK包发送给Sender,PUBACK包不包含消息体(Payload),可以改变的头部(Variable header)中有一个包头标识(Packet Identifier),以及它所接收到的Packet Identifier包中的Packet Identifier。
3)Sender接收到PUBACK后,将根据Packet Identifier中的Packet Identifier查找本地保存的PUBLISH包并将其丢弃,同时完成一次发送消息。
4)如果Sender未接收到相应于PUBLISH包的PUBACK,则将该PUBLISH包的DUP标识设置为1(表示已重新发送的PUBLISH包),然后重新发送PUBLISH包。在接收PUBACK之前重复此过程,然后执行步骤3。
QoS2:由Sender发出的消息,Receiver确保接收到并且仅接收到一次,也就是说Sender竭力将消息发送给Receiver,若发送失败,Receiver将继续重试,直到Receiver接收到消息,同时保证Receiver不会接收到重复的消息。
QoS2通过两组请求/回答过程(4段握手)确保Receiver从Sender接收到消息,并且没有重复:
1)Sender以PacketIdentifier为P发送QoS为2的PUBLISH包,并将其保存在本地;
2)Receiver接收到PUBLISH包后的PacketIdentifierP将PUBLISH包保存到本地,回覆Sender一个PUBREC数据包,Packet Identifier为P,PUBREC可变头部。无信息主体(Payload);
3)当Sender接收到PUBREC,它可以安全地丢弃Packet Identifier为P的初始PUBLISH包,与此同时,在对Receiver的PUBREL包进行回复的同时保存PUBREL包,PUBREL数据包可变的头部为P,不存在主体信息;如果发送器在某一段时间内未接收到PUBLISH包,则将PUBLISH包的DUP标识为1,重发PUBLISH包(Payload);
4)当Receiver接收到一个PUBREL包时,它可以丢弃保存的PUBLISH包的Packet Identifier P,回覆Sender一个PUBCOMP数据包,Packet Identifier在可变头部为P,无信息主体(Payload);
5)当Sender接收到一个PUBCOMP包,它认为数据包传输已经结束,它将删除相应的PUBREC包。当Sender未接收到某一PUBCOMP包时,它将重新发送PUBREL包。
在QoS2中,我们可以看到Sender和Reciever之间至少要发送4个包,QoS2是最安全、最慢的QoS级别。