esp-rs / std-training

Embedded Rust on Espressif training material.
https://esp-rs.github.io/std-training
Apache License 2.0
590 stars 75 forks source link

Whats the usage difference between EspMqttClient::new and EspMqttClient::new_cb ? #255

Closed AZarbade closed 3 months ago

AZarbade commented 3 months ago

TLDR: I want to know when should I be using EspMqttClient::new and EspMqttClient::new_cb ? Also I believe mqtt example should be updated.

documentation reference.

Note: I am using xtensa-esp32-.

Following the given mqtt example I am assuming that I need to use EspMqttClient::new_cb version. Which has been working as expected. Here is my code snippet:

let mut mqtt_client = EspMqttClient::new_cb(&broker_url, &mqtt_config, move |_msg| {})?;

However, when I try to use the other varient EspMqttClient::new nothing is getting published to the mqtt broker, even though I haven't changed the publishing method. Here is my code snippet:

let (mut mqtt_client, _mqtt_connection) = EspMqttClient::new(&broker_url, &mqtt_config)?;

What am I supposed to do with _mqtt_connection?

For reference, here is complete code snippet;

let mqtt_config = MqttClientConfiguration::default();
let mut mqtt_client = EspMqttClient::new_cb(&broker_url, &mqtt_config, move |_msg| {})?;

let payload: &[u8] = &[];
mqtt_client.publish("home/default", QoS::AtLeastOnce, true, payload)?;

Suggestion: The example defines the new client as follows, let mut client = EspMqttClient::new(&broker_url, &mqtt_config, move |_message_event| {})?; but the function has been updated to use EspMqttClient::new_cb instead for EspMqttClient::new. Updated code: let mut mqtt_client = EspMqttClient::new_cb(&broker_url, &mqtt_config, move |_message_event| {})?;

PS: This is literally my first bug report/pull request, so please let me know if I need to provide any additional information or if there are any issues with my report.

Vollbrecht commented 3 months ago

First you can have a look at our official example here. The technical difference between the two api's is that with the callback api, the things that need to be done will directly be called from within the thread that is executing the mqtt stack itself. This has pro's and con's. It maybe simpler to use as you don't have to fiddle with a messaging system, because you get everything directly handeld. One disadvantage is that you are executing in the mqtt stack itself, so you need to limit yourself with the work you are doing in the callback, so to not starve the system. The mqtt stack is executed in a higher priority thread. With the "new" api your execution runs in either your main thread or in a separate thread created by yourself. So your code is running in general in a lower priority compared to the still ruining mqtt-stack thread. This rises to some awkard problems at the start, but in general decouples the system a bit.

AZarbade commented 3 months ago

Looking at official example api does now make sense. I wonder as to why there is this discrepancy between the official API and the std_training example? I do get that std_training version is much simpler to execute and understand, I think it should point user to offical repo for "more details".

Anyways, thanks for helping me out.