MQTT lets programs exchange messages through a broker. Publishers send messages to named topics, and subscribers receive messages from the topics they follow.
These recipes need a Rye build with MQTT support and a running broker, such as Mosquitto. They use a local broker on port 1883. Give each connected client a unique client ID.
Use Open with an MQTT URI. The path after the broker address is the client ID.
client: Open mqtt://localhost:1883/rye-pub |^check "connect failed"
client .Publish-simple "sensors/temperature" "23.5"
|^check "publish failed"
client .Disconnect
Publish-simple sends a string payload with QoS 0 and no retention. Disconnect closes the connection; Close is an alias. client .Is-connected returns integer 1 when connected, otherwise 0.
If the URI has no client ID, it defaults to mqtt-client. Use explicit IDs to avoid clients disconnecting one another.
Run this subscriber in one terminal, then run the publisher above in another.
client: Open mqtt://localhost:1883/rye-sub |^check "connect failed"
client .Subscribe "sensors/temperature" 0 fn { payload msg } {
print payload
print [ "Topic:" msg."topic" ]
} |^check "subscribe failed"
print "Listening ..."
select { } ; keep the program running
The callback receives the payload string and a metadata dictionary. The dictionary contains topic (string), qos (integer), retained and duplicate (booleans), and message-id (integer). The payload is passed separately, not stored in the dictionary.
For QoS 0, Subscribe-simple lets you omit the QoS argument:
client .Subscribe-simple "sensors/temperature" fn { payload msg } {
print payload
} |^check "subscribe failed"
Both subscription methods now use the same callback signature and metadata fields. Compatibility note: older builds passed only metadata as the first argument to Subscribe-simple. Update those handlers to fn { payload msg } { ... }, or use Subscribe with QoS 0 when working with older builds.
A subscription can use + to match one topic level, or # to match all remaining levels.
; Match sensors/temperature and sensors/humidity
client .Subscribe "sensors/+" 1 fn { payload msg } {
print [ msg."topic" payload ]
} |^check "subscribe failed"
; Later, stop receiving messages for this subscription
client .Unsubscribe "sensors/+" |^check "unsubscribe failed"
For example, sensors/# also matches sensors/room1/temperature. Wildcards belong in subscriptions, not published topic names. Unsubscribe using the same filter you subscribed with.
Use Publish when you want to control delivery and retention:
client: Open mqtt://localhost:1883/rye-status |^check "connect failed"
; QoS 1, retained: new subscribers can receive the latest value
client .Publish "sensors/temperature" "23.5" 1 1
|^check "publish failed"
client .Disconnect
QoS can be 0 (at most once), 1 (at least once), or 2 (exactly once at the MQTT protocol level). Both publishing and subscribing accept a QoS level; a higher subscription QoS does not upgrade a QoS 0 publication.
The last argument is an integer retain flag: use 0 for ordinary messages and 1 to retain the latest message on that topic. To clear a retained value, publish an empty payload with retention enabled:
client .Publish "sensors/temperature" "" 1 1
This last snippet assumes an open client connection.
URI connections accept mqtt://[user:password@]host:port/client-id. Use mqtts:// for TLS:
; Replace this address with your TLS-enabled broker
client: Open mqtts://broker.example:8883/rye-secure
|^check "TLS connection failed"
Credentials and client IDs in URIs use URL percent-encoding for reserved characters. A client ID occupies a single path segment. Query strings and fragments are not supported.
For explicit configuration, use mqtt-options. Its setters return the same options object, so they can be chained:
opts: mqtt-options
|Set-broker "ssl://broker.example:8883"
|Set-client-id "rye-secure"
|Set-username "user"
|Set-password "replace-with-your-password"
|Set-keep-alive 60
client: opts |Connect-with-options |^check "connect failed"
client .Publish-simple "app/heartbeat" "ok" |^check "publish failed"
client .Disconnect
Set-broker takes a string with the transport scheme tcp:// or ssl://, unlike the Rye URI schemes mqtt:// and mqtts://. Keep-alive is in seconds. Configure options before connecting.
Use TLS when sending credentials over a network. Keep real passwords out of source files. These bindings do not expose custom CA or client-certificate configuration; TLS uses the underlying client’s default certificate verification.
A last will lets the broker announce that a client disappeared unexpectedly. Configure it before connecting, then publish an online status:
opts: mqtt-options
|Set-broker "tcp://localhost:1883"
|Set-client-id "rye-device"
|Set-keep-alive 30
|Set-will "devices/rye-device/status" "offline" 1 1
client: opts |Connect-with-options |^check "connect failed"
client .Publish "devices/rye-device/status" "online" 1 1
|^check "publish failed"
; Do the device's work here.
; On a planned shutdown, publish the status ourselves.
client .Publish "devices/rye-device/status" "offline" 1 1
|^check "publish failed"
client .Disconnect
Set-will takes a topic, string payload, QoS, and integer retain flag. Here both statuses are retained so new subscribers can see the latest status.
A normal Disconnect does not trigger the will. On an unexpected loss of connection, the broker publishes it after detecting the loss.
|^check "message" to add context and return on a failed operation.examples/mqtt/publisher.rye and examples/mqtt/subscriber.rye.