繁体   English   中英

ESP32-CAM 如何将大型二进制有效负载发布到 AWS IOT ssl mqtt 主题,测试了许多库但没有成功:-(

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM