[][src]Module svc_agent::mqtt::compat

MQTT 3.1 compatibility utilities.

mqtt-gateway supports both MQTT 3.1 and MQTT 5 protocol versions. However svc-agent is based on rumqtt MQTT client which only supports MQTT 3.1 because there's no pure Rust implementation of MQTT 5 client yet.

MQTT 5 introduces message properties that are somewhat like HTTP headers. An alternative for them in MQTT 3.1 is to send this data right in the message payload. So mqtt-gateway supports the envelope payload format convention which looks like this:

{
    "payload": "{ … }",
    "properties": {
        "name": "value"
    }
}

payload is the payload itself. Even if it's a JSON object by itself it needs to be serialized to string.

properties is an object of name-value pairs. All values must be strings.

mqtt-gateway does a translation between MQTT 3.1 envelope and plain MQTT 5 formats so clients may talk to each other using different versions of the protocol. When an MQTT 5 client sends a message to an MQTT 3.1 client it sends plain payload and properties using MQTT 5 features but latter client receives it in the envelope format. And vice versa: published an MQTT 3.1 envelope will be received as a plain MQTT 5 message by an MQTT 5 client.

This module implements the agent's part of this convention.

Use serde to parse an incoming envelope. Here's an example on how to parse an incoming message:

#[derive(DeserializeOwned)]
struct RoomEnterRequestPayload {
    room_id: usize,
}

let envelope = serde_json::from_slice::<compat::IncomingEnvelope>(payload)?;

match envelope.properties() {
    compat::IncomingEnvelopeProperties::Request(ref reqp) => {
        // Request routing by method property
        match reqp.method() {
            "room.enter" => match compat::into_request::<RoomEnterRequestPayload>(envelope) {
                Ok(request) => {
                    // Handle request.
                }
                Err(err) => {
                    // Bad request: failed to parse payload for this method.
                }
            }
        }
    }
    compat::IncomingEnvelopeProperties::Response(ref respp) => {
        // The same for response.
    }
    compat::IncomingEnvelopeProperties::Response(ref respp) => {
        // The same for events.
    }
}

Enveloping of outgoing messages is up to svc-agent. Just use (Agent::publish)[../struct.Agent.html#method.publish] method to publish messages.

Structs

OutgoingEnvelope

Outgoing enveloped message.

Enums

OutgoingEnvelopeProperties

Properties of an outgoing envelope.

Traits

IntoEnvelope