marvinroger / async-mqtt-client

📶 An Arduino for ESP8266 asynchronous MQTT client implementation
MIT License
848 stars 268 forks source link

Delay between MQTT messages #270

Open sude22 opened 2 years ago

sude22 commented 2 years ago

Hi, I'm using the lib with homie-esp8266. It works quite stable since the last bugfixes.

I just have a question about the delay (about 1 sec.) between each MQTT message send from the device, e.g. on start-up. Is there a reason why that delay have to be that long? Is that a homie or async-tcp-client thing?

I have a device with 4 inputs, if they are toogled at the same time, the messages need 4 seconds to send.

Maybe I missed something...

Thanks for your great work on this lib.

Regards

bertmelis commented 2 years ago

In the current implementation, messages are put in a queue and sent one by one. This means, if you send messages with QoS > 0 (which Homie does), the messages do have a delay because the mqtt client waits for the acknowledgement before sending the next. Hence the delay.

I've been thinking to improve this but I currently don't have time to do this.

sude22 commented 2 years ago

Hey Bert, thank you for that info. Maybe there is a way to reduce the time of the acknowledgement.

bertmelis commented 2 years ago

Are you running this on esp8266 or esp32?

Option in this lib are really limited. 1 second however is very slow. Can you wireshark the traffic on your WiFi?

sude22 commented 2 years ago

It is a esp8266. I have a look at my Mosquitto config, but I changed nothing to the default IOTStack installation... It runs with no problems till now.

stedon81 commented 9 months ago

Hi @bertmelis I have experienced exactly the same problem. I'm on an ESP8266, using the Homie lib (https://github.com/homieiot/homie-esp8266). With the version 0.9.0 of async-mqtt-client, all MQTT messages that are published with qos=1 are sent in a very low frequency. In my case, it is 2 messages per second in my lab environment (perfect WIFI conditions).

I have realized that this is due to the fact that this version of your lib explicitly waits for the TCP ack before sending the next message. On ESP8266, the TCP ack very frequently only comes after several 100ms. Not sure, if this is a problem of the underlying ESPAsyncTCP lib.

However, I noticed that in v0.9.0 of your lib all MQTT ack functions (_onUnsubAck(), _onSubAck(), _onConnAck()) contain a call to _handleQueue() at the end to immediately process the next message in the queue, except for _onPubAck(). For PUBLISH, you explicitly wait for the TCP ack, which calls _handleQueue() in the _onAck(). Is there any reason for this?

If I add _handleQueue() to _onPubAck() as well, then I get a throughput of 40 messages per second with qos=1.

void AsyncMqttClient::_onPubAck(uint16_t packetId) {
  _freeCurrentParsedPacket();
  if (_head && _head->packetId() == packetId) {
    _head->release();
    log_i("PUB released %u", packetId);
  }
  for (auto callback : _onPublishUserCallbacks) callback(packetId);
  _handleQueue();  // publish confirmed, ready to send next queued item
}

Please let me know if you see any problems that could arise from adding this line.

Regards, stedon81