Rumqttc now supports MQTT5

Rumqttc now supports MQTT5

MQTT is a popular protocol used in IoT (Internet of Things) devices for communication between devices and servers. It has a simple publish-subscribe messaging model and is designed for reliable, efficient, and lightweight communication. With the latest release rumqttc, our Rust MQTT client library, now supports several new features in MQTT 5 protocol.

Here are some of the new features introduced in MQTT 5 that you can take advantage of using rumqttc:

Connect Properties

Connect properties are a new feature introduced in MQTT 5 protocol that allow clients to add various properties to the Connect packet, such as session expiry interval, maximum packet size, maximum topic alias, and more.

To customise these properties, you have two options: You can either create an MqttOptions struct and individually set the desired options, or you can create a ConnectProperties struct and pass it to the set_connect_properties() method.

Once you have defined the options, you can use them to initialise a new client with the AsyncClient::new method. With the client, you can then use the available methods to subscribe and publish messages with properties.

Here's some sample code using connect properties with rumqttc:

// --snip--

let mut mqttoptions = MqttOptions::new("test-1", "broker.emqx.io", 1883);
mqttoptions.set_keep_alive(Duration::from_secs(5));
mqttoptions.session_expiry_interval(5.into());
mqttoptions.set_topic_alias_max(10.into());

let (client, mut eventloop) = AsyncClient::new(mqttoptions, 10);

// --snip--

Message Expiry Interval

The message expiry interval is a new feature introduced in MQTT 5 that allows clients to set a time-to-live (TTL) value for messages that they publish. This feature ensures that messages are automatically deleted by the broker after a certain period of time, regardless of whether the message has been delivered or not. In rumqttc, you can use the PublishProperties struct to set the message_expiry_interval field to a duration value.

// --snip--

// Construct PublishProperties and set the message_expiry_interval field
let mut props = PublishProperties::default();
props.message_expiry_interval = Some(1000.into());

// Publish a message on the topic "hello/world" with QoS level set to ExactlyOnce, the retain flag set to false, properties equal to `props` and a payload of three copies of the byte 3.
client.publish_with_properties(
        "hello/world",
        QoS::ExactlyOnce,
        false,
        vec![3; 3],
        props.clone(),
    )
    .await
    .unwrap();

// --snip--

User Properties

User properties in MQTT 5 can be added to almost every type of MQTT packet, except for PINGREQ and PINGRESP. They are basic UTF-8 string key-value pairs, similar to HTTP headers, that can be used to pass any information between publisher, broker, and subscriber. This allows users to extend the standard protocol features and add metadata to MQTT messages to meet their specific needs. Additionally, user properties can be used to provide context to the message content, such as including device ID, serialization, and compression information in the message payload. This makes it easier for subscribers to understand and process messages without needing to infer this information from the topic.In rumqttc, you can use the PublishProperties struct to set user properties with the user_properties field on a Publish packet.

// --snip--

// Set the user_properties field on PublishProperties
props.user_properties = vec![("hello".into(), "world".into())];

// Send publish with `props`
client.publish_with_properties(
        "hello/world",
        QoS::ExactlyOnce,
        false,
        vec![3; 3],
        props.clone(),
    )
    .await
    .unwrap();

// --snip--

Request Response

In MQTT 5, there is a new feature for facilitating the request-response model which enables clients to designate a specific topic for response messages. To set the response_topic field for a Publish packet you can use the PublishProperties struct as follows:

// --snip--

// Set the response_topic field on PublishProperties
props.response_topic = Some("response".into());

client.publish_with_properties(
        "hello/world",
        QoS::ExactlyOnce,
        false,
        vec![3; 3],
        props.clone(),
    )
    .await
    .unwrap();

// --snip--

Topic Aliases

Using topic aliases clients can send a numeric alias to represent a previously established topic. This helps reduce the number of bytes needed to represent topic names in MQTT messages, thereby saving bandwidth and improving performance.

In rumqttc, you can set the maximum number of topic aliases that the server can use with set_topic_alias_max() on MqttOptions used to initialize the client , and use them while publishing messages by setting the topic_alias field on PublishProperties for a publish packet.

// --snip--

// Set the topic alias field to 28 on PublishProperties
props.topic_alias = Some(28);

// Establish topic->alias map for the server, ie “hello/world”->28
client.publish_with_properties(
        "hello/world",
        QoS::ExactlyOnce,
        false,
        vec![3; 3],
        props.clone(),
    )
    .await
    .unwrap();

// Publish without a `topic` using just the alias, 28.
client.publish_with_properties(
        "",
        QoS::ExactlyOnce,
        false,
        vec![3; 3],
        props.clone(),
    )
    .await
    .unwrap();


// --snip--

If you're interested in learning more about Rumqtt, be sure to check out our Github repository where you can find examples of how to use Rumqtt in the examples directory, including an complete example of how to use topic aliases.

And don't forget to join our Discord server and star the repository to stay up to date on the latest developments!