knolleary / pubsubclient

A client library for the Arduino Ethernet Shield that provides support for MQTT.
http://pubsubclient.knolleary.net/
MIT License
3.82k stars 1.47k forks source link

MQTT Image send, lost bytes #608

Open eduml7 opened 5 years ago

eduml7 commented 5 years ago

Hi,

I am trying to send a frame from an ESP32 cam to a Java server with this MQTT lib. I am able to capture the image, but when I try to send it over MQTT with this method client.write(fb->buf, fb->len); it only sends some bytes (83224 bytes of the photo and 22950 bytes sent). I have tried too a loop over the bytes and send byte-per-byte with the same result.

for (int i = 0; i < fb->len; i++) {
   client.write(fb->buf[i]);
}

I have achieved it using this other method but it takes a lot of time to transmit the data:

client.publish_P("topic", fb->buf, fb->len, false);

Any ideas?

eduml7 commented 5 years ago

I am using mosquitto as broker, and on its logs this is what I see:

1556567535: Received PUBLISH from ESP32Client (d0, q0, r0, m0, 'home/orchard/watcher', ... (200055 bytes)) 1556567535: Sending PUBLISH to paho22444007144826 (d0, q0, r0, m0, 'home/orchard/watcher', ... (200055 bytes)) 1556567535: Received PUBLISH from ESP32Client (d0, q0, r0, m0, 'home/orchard/watcher', ... (3447 bytes)) 1556567535: Sending PUBLISH to paho22444007144826 (d0, q0, r0, m0, 'home/orchard/watcher', ... (3447 bytes)) 1556567535: Socket error on client ESP32Client, disconnecting.

client.beginPublish("home/orchard/watcher", buf_len, false); size_t meison = 0; static const size_t bufferSize = 4096; static uint8_t buffer[bufferSize] = {0xFF}; while (buf_len) { size_t copy = (buf_len < bufferSize) ? buf_len : bufferSize; Serial.println(copy); memcpy ( &buffer, &fb->buf[meison], copy ); client.write(&buffer[0], copy); buf_len -= copy; meison += copy; } client.endPublish();

Seems some kind of socket error, but I dont know what could be. I tried to change some parameters like MQTT_MAX_TRANSFER_SIZE but everytime the same behavior... :(

eduml7 commented 5 years ago

Bad luck, it seems that taken photos where too small enough to make the sending work... I am expecting the same behavior again... It seems that broker marks as finished the byte transfer, because I see the loop logging traces (still writing) and the broker already received the message:

1556578553: Received PUBLISH from ESP32Client (d0, q0, r0, m0, 'home/orchard/watcher', ... (4308 bytes)) 1556578553: Sending PUBLISH to paho34922439777099 (d0, q0, r0, m0, 'home/orchard/watcher', ... (4308 bytes))

eduml7 commented 5 years ago

I have changed from Mosquitto to HiveMQ and same behavior

pcbtborges commented 5 years ago

Hello there... Same problem, cannot publish ESP32CAM photo to Mosquitto. Did you get the solution for the problem? Thanks Paulo

eduml7 commented 5 years ago

Hi Paulo,

I have workarounded it by sending small images over MQTT, configuring the camera with the following values:

camera_config_t config;
...
  config.pixel_format = PIXFORMAT_JPEG;
  config.frame_size = FRAMESIZE_SVGA;
  config.jpeg_quality = 12;
...
esp_err_t err = esp_camera_init(&config);

With this parameters you get enough quality to send the images and not blocks the sending process. Images are 800x600 and its OK for me. But if anybody has a better solution, please share...

ralawa commented 4 years ago

Hi,

Just replace in publish_P:

for (i=0;i<plength;i++) { rc += _client->write((char)pgm_read_byte_near(payload + i)); }

with:

rc += _client->write(payload, plength);

For me the large-payload API is buggy. It doesn't generate a valid header. If you compare header generated by publish_P and beginPublish they are not the same.

Regards,