For the complete documentation index, see llms.txt. This page is also available as Markdown.

MQTT Binding

The MQTT binding provides integration with MQTT 5 message brokers for Rumi microservices.

Overview

The MQTT binding connects a Rumi microservice to any MQTT 5 broker (for example Mosquitto, HiveMQ, or EMQX). MQTT is a natural fit for the SMA messaging model because both are topic based publish and subscribe systems, so channel keys map directly onto MQTT topics with no delimiter rewriting.

The binding speaks MQTT 5 only. It does not fall back to MQTT 3.1.1, because it relies on an MQTT 5 feature (Correlation Data) to carry Rumi's message metadata alongside the payload.

Two operating modes

The binding operates in one of two modes, and choosing the right one is the first decision when you configure it:

  • Default (metadata) mode — the binding carries Rumi's message metadata on the wire (in MQTT 5 Correlation Data) alongside the payload. Use this for Rumi-to-Rumi messaging over MQTT, where both ends are Rumi microservices.

  • Raw mode (raw_mode=true) — the binding puts only the payload on the topic, with no Rumi metadata. Use this to integrate with an external, non-Rumi source or sink (IoT devices, telemetry feeds, an existing MQTT broker). See Connecting to External Systems.

External integration is the most common reason to use the MQTT binding, so if you are connecting to anything that is not itself a Rumi service, you almost certainly want raw mode. It is not the default, and the binding does not infer it — you must set raw_mode=true (see the note in Connecting to External Systems on what happens if you forget).

For configuration details, see MQTT Binding Configuration.

This is a first release of the MQTT binding. It supports BestEffort delivery. Guaranteed delivery is not yet supported, see Quality of Service below.

MQTT Topic Format

MQTT uses / as its topic level separator, which is the same delimiter Rumi uses for hierarchical channel keys. As a result the binding uses channel keys as MQTT topics directly, unlike the Kafka and JMS bindings which rewrite / to . for their providers.

For example, a channel with the key orders/US/IBM publishes to, and subscribes from, the MQTT topic orders/US/IBM.

Wildcard Topics

MQTT topic filters support two wildcards, and the binding maps Rumi's channel filter wildcards onto them when a channel is joined:

Rumi filter wildcard
MQTT wildcard
Description

*

+

Matches a single topic level.

>

#

Matches the remainder of the topic. May only appear as the last level of a filter.

The mapping is applied only on the subscribe path. A published topic name is always fully qualified, since MQTT does not permit wildcards in a published topic.

Message Metadata

The binding carries Rumi's message metadata in the MQTT 5 Correlation Data field, which is the only binary companion slot the protocol offers alongside a payload. The serialized message payload travels in the MQTT payload, and the metadata travels in the correlation data. This mirrors the way the Kafka binding uses the record key to carry metadata.

MQTT 5 user properties were considered for this purpose but not used, because they are UTF-8 string pairs and would require base64 encoding of the binary metadata.

This section describes the default (metadata) mode, which is intended for Rumi-to-Rumi messaging. A consequence of carrying metadata in correlation data is that a non-Rumi MQTT subscriber can still read the payload of a message published by Rumi, but it will not interpret the correlation data. In the other direction, a message that arrives on a metadata-mode channel without correlation data is treated as corrupt and raised as an Unhandled Message, not silently accepted — to consume metadata-less messages you must use raw mode (below).

Connecting to External (Non-Rumi) Systems (Raw Mode)

To integrate with a non-Rumi MQTT source or sink, run the channel's bus in raw mode by setting raw_mode=true on the bus descriptor. In raw mode:

  • Outbound — the binding publishes only the serialized message payload to the resolved topic, with no correlation data. An external subscriber sees a plain MQTT message. Choose a message encoding the external system understands (for example a JSON or bytes message), since there is no Rumi metadata to describe it.

  • Inbound — a message that arrives with no metadata is accepted (rather than rejected as corrupt) and delivered to the application as a bytes message. A channel subscribes an MQTT topic filter — for example sensors/+/temp — and the messages it attracts are delivered to your handlers.

Metadata mode and raw mode are mutually exclusive per bus: a raw-mode bus cannot also carry Rumi metadata, so a single MQTT bus is either a Rumi-to-Rumi bus or an external-integration bus, not both.

Quality of Service

SMA defines two qualities of service, and MQTT defines three. The binding maps them as follows:

SMA QoS
MQTT QoS
Status

BestEffort

0 (at most once)

Supported.

Guaranteed

1 (at least once)

Not supported in this release.

In this release, a Guaranteed send is rejected with an exception rather than being silently downgraded to best effort. A Guaranteed channel may still be created and joined for inbound traffic, but any attempt to send on it fails.

See Also

Last updated