MQTT Broker

A full MQTT 3.1.1 broker built into the same server — publish/subscribe messaging for IoT and event streams. mosquitto_pub/mosquitto_sub and any MQTT client library work unmodified. Off by default.

Enable it

# start the MQTT listener (1883 is the MQTT default port)
OXIDB_MQTT_PORT=1883 ./oxidb-server

Publish & subscribe

# terminal 1 — subscribe
mosquitto_sub -h 127.0.0.1 -p 1883 -t sensors/temp

# terminal 2 — publish
mosquitto_pub -h 127.0.0.1 -p 1883 -t sensors/temp -m "22.4"

Topic wildcards

WildcardMatchesExample
+Exactly one levelsensors/+/tempsensors/a/temp, sensors/b/temp
#The whole subtreesensors/# → everything under sensors/

Retained messages

Publish with the retain flag to deliver the last-known value to any new subscriber immediately. An empty retained payload clears it.

mosquitto_pub -h 127.0.0.1 -p 1883 -t status/device1 -m online -r
mosquitto_sub -h 127.0.0.1 -p 1883 -t status/device1   # gets "online" at once

QoS & Last Will

  • QoS 1 — genuine at-least-once: a delivered message is held until the subscriber PUBACKs it, and retransmitted with DUP on reconnect if it does not.
  • QoS 2 — genuine exactly-once, both directions: subscriptions are granted at QoS 2, the broker runs the full PUBREC / PUBREL / PUBCOMP state machine outbound, and a retransmitted inbound PUBLISH (same packet id, DUP) is re-acked but never fanned out twice. With persistence on, a PUBREL owed at crash time is still owed after restart.
  • Persistent sessions (clean_session=false) — a subscriber that drops keeps its subscriptions, and messages published while it is offline are queued (bounded) and delivered on reconnect, with session_present=1. With OXIDB_MQTT_PERSIST=1, sessions, queued messages and retained topics are written through the document engine's WAL and survive a crash — an acknowledged QoS 1 message outlives a SIGKILL. Without it, sessions are in-memory and a restart is a clean slate.
  • Last Will & Testament — a client's will message is published automatically on an abnormal disconnect or keepalive expiry (enforced at 1.5× the keepalive).
# will published if this client drops without a clean DISCONNECT
mosquitto_sub -h 127.0.0.1 -p 1883 -t data \
  --will-topic status/me --will-payload offline --will-qos 1

Authentication

Require matching CONNECT credentials with two env vars:

OXIDB_MQTT_PORT=1883 OXIDB_MQTT_USER=iot OXIDB_MQTT_PASSWORD=secret ./oxidb-server

mosquitto_pub -h 127.0.0.1 -p 1883 -u iot -P secret -t t -m hi

Cross-protocol pub/sub

The broker shares its subscriber layer with OxiMem: a message PUBLISHed over the Redis (RESP) protocol can reach MQTT subscribers, and vice-versa — one pub/sub bus, two wire protocols.

# publish from the Redis side...
redis-cli -p 6379 PUBLISH sensors/temp "22.4"
# ...an MQTT client subscribed to sensors/temp receives it

It also bridges to AMQP through the pre-declared amq.topic exchange (the RabbitMQ MQTT-plugin mapping, / ↔ .): a sensor publishes MQTT, a RabbitMQ-client worker pool consumes it as a work queue.

For real-time document subscriptions over WebSocket (Firebase-style onSnapshot), see Streams.

Report Issue