我正在嵌入式设备上使用IoTHub设备客户端SDK。该应用程序将定期将遥测消息发送到物联网集线器。物联网设备连接到无线路由器,并通过WAN端口无线连接到互联网。
当无线路由器失去互联网连接时,物联网设备将不会立即收到有关断开连接的通知。大约需要60秒钟才能收到通知,然后该物联网设备将继续通过IoTHubDeviceClient_LL_SendEventAsync()发送遥测消息,所有这些消息都将排入SDK层并占用内存。由于它位于资源有限的嵌入式设备上,因此内存被消耗掉,并导致程序被较低的内存杀手级应用杀死。
是否可以在sdk层中排队指定Iot消息的总大小?如果超过此配额,则IoTHubDeviceClient_LL_SendEventAsync()将立即失败。
实际上,正常情况下也需要这样做。当物联网设备发送消息时,似乎消息已在低层排队并在特定时间被冲走。我看不到任何可以控制冲洗的API。即使在存在Internet连接的情况下,这也从应用程序级别产生了另一个问题,无法控制已排队的消息数和已排队的时间,因此,应用程序无法控制进程使用了多少内存。我的设备上有一个系统监视器,它将杀死进程使用过多的内存。
答案 0 :(得分:2)
问题是,即使在队列已满的情况下发生消息故障,即使在那种情况下您也要怎么办?那么,由于存储容量不足,您会丢失信息吗?从物联网的角度来看,我建议在这种情况下考虑您的设备是否是可靠的物联网设备,以应对这些极端情况。此外,了解设备的局限性以及了解没有Internet连接可以持续多长时间有助于减轻应用程序(而非SDK)带来的这些风险。
在GitHub上,默认的sendMessageAsync方法会在消息发送失败的情况下引发超时异常,除非您已实施某种重试策略(根据文档C SDK不允许自定义重试策略) https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-reliability-features-in-sdks)。
根据基于重试策略的连接失败的文档(如果已设置),SDK将尝试以这种方式或以这种方式启动连接,并将在此期间创建的消息排队: https://github.com/Azure/azure-iot-sdk-c/blob/master/doc/connection_and_messaging_reliability.md
因此,这里的期望是SDK对内存限制不承担任何责任。这取决于应用程序要处理。由于您的设备有一些限制,因此我建议您实施自己的排队机制(可以将重试设置为策略,这样可以避免排队)。这样,您可以控制在没有Internet连接且受控制的内存限制的情况下将发生的情况。也许您的业务案例接受了您计算的平均值,并且在一段时间内等了1条消息,而不是50条。
如果您不喜欢这种方式,文档还会说您设置了队列的超时时间-也许不是内存限制,但是超时是,所以也许您可以尝试对此进行更深入的研究:
“此系统中有两个超时控件。iothub_client_ll层中的原始控件-控制“等待发送”队列-协议传输层中的现代控件-适用于“进行中”列表但是,由于IoTHubClient_LL_DoWork导致遥测消息被立即*处理,发送并移动到“进行中”列表,因此第一个超时控件实际上是不适用的。
用户都可以通过IoTHubClient_LL_SetOption对其进行微调,因此,删除原始控件可能会给现有客户造成中断。因此,它保持原样,但是当我们移至该产品的下一个主要版本时,它将进行重新设计。”