【问题标题】:How often does a MQTT client check for new messages?MQTT 客户端多久检查一次新消息?
【发布时间】:2022-02-02 01:30:55
【问题描述】:
我对 MQTT 客户端如何接收新消息感到有些困惑。
MQTT 客户端多久轮询一次新到达的消息?
对于我们的应用程序,我们希望将 MQTT 设备连接到 AWS IoT Core 并在几天内不断检查消息。但我们希望减少用于检查新消息的蜂窝数据量。假设我们只想每 5 分钟检查一次新消息。我需要更改哪个 MQTT 参数?
我了解 MQTT 客户端不使用轮询来检查新消息,但如果消息在线,MQTT 代理会将消息转发给客户端。
但是客户端必须有某种持续的检查来接收消息,对吗?
我们知道客户端会在保活超时结束之前发送一个 PINGREQ 数据包,让代理知道它仍然处于活动状态。客户端是否在此 ping 期间检查新消息?
【问题讨论】:
标签:
amazon-web-services
tcp
mqtt
iot
aws-iot
【解决方案1】:
首先,您必须了解 MQTT 使用发布-订阅消息传递模式并且没有请求/响应。因此,在客户端,您不要求提供特定数据,并且可以定义询问的时间和频率。相反,只要您订阅的特定主题有更新,您就会自动收到通知。
因此,控制消息流的正确方法是在发布站点上完成 - 如果您只希望每 5 分钟发送一条消息,那么它应该只在此时间间隔内发布。
如果您的发布客户端确实有充分的理由每秒发布一个主题,但您的订阅者仍希望每 5 分钟检查一次,事情就会变得更加困难。在这种情况下,我认为最干净的方法是取消订阅该主题并在您想要更新时重新订阅它,或者您只是断开连接并在一段时间后重新连接。
在技术站点上,您通常有一个阻塞通信线程等待传入消息,一旦有传入消息,它将立即调用一些回调。但也有客户端实现让您有机会手动执行网络操作。
该线程还处理发送PINGREQ 和接收PINGRESP,但它会独立地注意到传入的订阅(您也可以使用keepalive of 0 禁用ping,但仍然可以获得您的订阅)。
话虽如此,停止/重新启动通信线程以控制您的消息流并不是一个好主意,因为这会阻止处理所有包,并会导致代理由于缺少PINGREQ 而断开您的客户端
【解决方案2】:
MQTT 协议已经为低带宽而设计 - 只要设备已连接(定期发送 PINGREQ),新消息就会通过 TCP 流发布。在客户端没有轮询新消息。只要您的蜂窝服务提供商允许您保持 TCP 连接打开,PINGREQ 的发送频率就可以降低。
或者,考虑使用AWS IoT Device Shadow,该服务可以帮助实现设备的虚拟表示并且更接近您所描述的 - 您的设备可以独立于更新本身轮询此服务以获取状态更新。可以使用 MQTT 或 HTTP/REST 完成轮询。
您必须进行一些试验,以确定哪个选项在带宽方面更适合您的用例。