如何解决ESP32-CAM如何将大型二进制有效负载发布到AWS IOT ssl mqtt主题,测试了许多库,但均未成功:-
我目前正在研究一个ESP32CAM项目,以在AWS IOT主题上发布一些高分辨率(UXGA)相机拍摄的照片。 我已经设法将一些带有属性的简短json负载发布到了不同的AWS IOT证书保护的主题,但是我面临着一个烦人的问题,那就是要对大型负载进行与捕获二进制文件相同的操作。
我浏览了许多站点,论坛,测试了不同的库,例如MQTT,PubSubClient,AsyncMQTTClient ...,但是我没有找到真正有效的解决方案用于大负载 >大约100KB。
例如,对于PubSubClient库,我尝试使用BeginPublish,write,endPublish方案对二进制有效负载进行分段,如下所示:
bool publishBinary(const uint8_t *buffer,size_t len,const char *topicpubName)
{
Serial.print("publishing binary ["+(String)len+"] ...");
if (len == 0) {
// Empty file
Serial.println("Error : binary payload is empty!");
return(false);
}
if (!client.beginPublish(topicpubName,len,false)) {
Serial.println("MQTT beginPublish Failed.");
return(false);
}
size_t max_transfer_size=80;
size_t n=0;
size_t size_send;
size_t offset=0;
while ((len-offset)>0) {
n=(len-offset);
if (n > max_transfer_size)
n=max_transfer_size;
size_send=client.write((const uint8_t *)(buffer+offset),n);
Serial.printf("%d/%d : %.02f %%\n",offset,(double)((100*offset)/len));
//Serial.println("n: "+(String)n+" - send: "+(String)size_send);
if(size_send != n) {
// error handling. this is triggered on write fail.
Serial.println("Error during publishing..."+(String)size_send+" instead of "+(String)n);
client.endPublish();
return(false);
} else {
offset+=size_send;
}
}
client.endPublish();
Serial.println("ok");
return(true);
}
客户端定义为 PubSubClient客户端(net),其中net是具有经过验证的CA_cert,证书和私钥的WiFiClientSecure对象。
MQTT连接运行良好,但是当我尝试发布较大的二进制有效负载时,该函数将缓冲区分段成块,直到最后,但总是会出现类似未知错误代码(0050)的错误或成功发布后,仅一小部分有效负载会发布到目标上。在这种情况下,我的jpeg文件在有效负载到达的S3存储桶上被截断了。
我不得不说,有时候,我设法发布了65K的有效载荷,但是有点运气...:-)
我已经在网上寻找了一些示例,但通常是用于较小的负载。如帖子中所述,我已经测试了PubSubClient中的Publish_P(...),但结果相同,在传输过程中它会中止。
我开始问自己,是否真的可以通过mqtt主题进行操作,还是必须创建一个带有lambda的API网关来处理如此大的有效负载。告诉我我错了:-)
如果您知道一个真正可行的大型有效载荷发布的好的解决方案,我将很高兴与您讨论:-)
谢谢!
解决方法
嘿,我在PubSubClient库和大文件方面也遇到了问题。最后,我发现必须按如下方式更新PubSubClient.h:
//128000 = 128 kB is the maximum size for AWS I think..
#define MQTT_MAX_PACKET_SIZE 100000
// It takes a long time to transmit the large files
// maybe even more than 200 seconds...
#define MQTT_KEEPALIVE 200
#define MQTT_SOCKET_TIMEOUT 200
,
#include <PubSubClient.h>
void setup() {
...
boolean res = mqttClient.setBufferSize(50*1024); // ok for 640*480
if (res) Serial.println("Buffer resized."); else Serial.println("Buffer resizing failed");
...
}
我正在使用50kB缓冲区,它工作得很好,没有尝试超出此范围,它也应该与100kB一起工作。
按照通常的方式调整缓冲区发布的大小之后。
顺便说一句,setBufferSize函数是最近才添加的IIRC。
,我遇到了同样的问题,我发现 PubSubClient 的 bufferSize
被定义为 uint16_t
。
https://github.com/knolleary/pubsubclient/blob/v2.8/src/PubSubClient.h#L92
因此,我们不能将缓冲区大小扩展到 64 kB 以上,也不能发布大型负载。
Michael's comment 可能会对您有所帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。