![](/img/trans.png)
[英]How to connect an ESP32 to MQTT server with public IP and SSL?
[英]ESP32-CAM how to publish large binary payload to AWS IOT ssl mqtt topic, tested many libs without success :-(
我目前正在从事一个 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,len,(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);
}
client 定义为PubSubClient client(net) ,其中 net 是 WiFiClientSecure 对象,带有经过验证的 CA_cert、cert 和私钥。
MQTT 连接运行良好,但是当我尝试发布大型二进制有效负载时,该函数将缓冲成块直到最后,但总是会出现诸如UNKNOWN ERROR CODE (0050) 之类的错误,或者当它成功发布时,只有一小部分部分有效载荷发布在目标上。 在这种情况下,我的 jpeg 文件在负载所在的 S3 存储桶上被截断。
我不得不说,有时,我设法发布了 65K 的有效载荷,但就像运气一样...... :-)
我在网上寻找了一些例子,但通常是针对小负载的。 正如在帖子中提到的,我已经测试了来自 PubSubClient 的 Publish_P(...) ......但结果相同,它在传输过程中中止。
我开始问自己 mqtt 主题是否真的有可能,或者我是否必须使用 lambda 创建一个 API 网关来处理如此大的有效负载。 告诉我我错了:-)
如果您知道真正有效的大型有效负载发布的好解决方案,我很乐意与您讨论:-)
谢谢 !
#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 库和大文件的问题。 最后我想通了,我必须更新 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
我遇到了同样的问题,我发现 PubSubClient 的bufferSize
被定义为uint16_t
。
https://github.com/knolleary/pubsubclient/blob/v2.8/src/PubSubClient.h#L92
因此,我们不能将缓冲区大小扩展到 64 kB 以上,也不能发布大型负载。
迈克尔的评论可能对你有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.