eclipse / paho.mqtt.rust

paho.mqtt.rust
Other
527 stars 102 forks source link

can set_payload function be added to MessageBuilder class #139

Closed goutham2688 closed 2 years ago

goutham2688 commented 2 years ago

type of issue: improvement or how to, if the functionality doesn't exist already.

issue: in certain cases I'd be receiving a mqtt message, and in response I'll be updating the status of the request in multiple publishes to the same topic. I feel instead of initializing the message via MessageBuilder, I'd like to update just the payload. and use the same msg structure multiple sense.

current working:

// Create a message and publish it
let msg = mqtt::MessageBuilder::new()
    .topic("test")
    .payload("test1")
    .qos(1)
    .finalize();

if let Err(e) = cli.publish(msg) {
    println!("Error sending message: {:?}", e);
}

let msg = mqtt::MessageBuilder::new()
    .topic("test")
    .payload("test2")
    .qos(1)
    .finalize();

if let Err(e) = cli.publish(msg) {
    println!("Error sending message: {:?}", e);
}

proposed look:

let msg = mqtt::MessageBuilder::new()
    .topic("test")
    .payload("test1")
    .qos(1)
    .finalize();

if let Err(e) = cli.publish(msg) {
    println!("Error sending message: {:?}", e);
} 

msg.set_payload("test2")

if let Err(e) = cli.publish(msg) {
    println!("Error sending message: {:?}", e);
}
fpagliughi commented 2 years ago

Well, the cli.publish(msg) call takes ownership of the message, so we can't update the payload after that because the msg is no longer in scope.

The reason to "give" the message to the client for publishing , instead of passing a shared reference, is mostly for the async varieties of the client. When publish() returns, the operation has only been initiated and has not yet been completed. So the msg object couldn't be mutated since the client was still using it. Passing ownership of the message into the client solves this problem.

There is an alternate way to do what you want, though. Use the Topic struct. This is meant for your exact use case: when you want to repeatedly publish messages with different payloads to the same topic. Use it like:

let topic = mqtt::Topic::new(&cli, "test", QOS);
topic.publish("payload1");
topic.publish("payload2");

This does assume that cli is an AsyncClient. If you're using the synchronous Client, I suppose we can make a sync variety, or see if we can make it generic.

goutham2688 commented 2 years ago

Thanks for the explanation :) I'm currently using the sync client.

fpagliughi commented 2 years ago

Added SyncTopic for this. Feel free to reopen this issue if there are any further problems.