[][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 messsage 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

IncomingEnvelope

Incoming enveloped message.

OutgoingEnvelope

Outgoing enveloped message.

Enums

IncomingEnvelopeProperties

Enveloped properties of an incoming message.

OutgoingEnvelopeProperties

Properties of an outgoing envelope.

Traits

IntoEnvelope

Functions

into_event

Parses an incoming envelope as an event with payload of type T.

into_request

Parses an incoming envelope as a request with payload of type T.

into_response

Parses an incoming envelope as a response with payload of type T.