Durable messaging
In this tutorial you give the gateway a stream and two buckets. Then you publish at QoS 1 and 2, retain a message, and keep a session across a gateway restart.
Before you start
You need:
- The
mq-gatewaybinary from Getting started. No gateway or playground must be running. nats-serverand thenatsCLI.- The MQTTX CLI.
- On a licensed build, your license file. See Install.
In each terminal, point the nats CLI at the local server:
export NATS_URL=nats://127.0.0.1:4222
1. Start NATS with JetStream
nats-server -js -sd ./js-data
The server listens on port 4222 and stores JetStream data in ./js-data.
Keep it running.
2. Create the stream and the buckets
-
Save this config as
gateway.yaml:bindings:- { subjects: [plant1.*.*.alarms], stream: ALARMS }mqtt:bindings: [ALARMS]retained: { bucket: MQTT_RETAINED }sessions: { bucket: MQTT_SESSIONS }The binding stores the topics
plant1/+/+/alarmsin the streamALARMS. Themqttblock serves MQTT on port 1883. -
Create the stream and the buckets that the config names:
nats stream add ALARMS --subjects 'plant1.*.*.alarms' --deny-delete --deny-purge --defaultsnats kv add MQTT_RETAINED --history 2nats kv add MQTT_SESSIONS --history 1The gateway never creates them for you.
-
Check them:
./mq-gateway check --config gateway.yaml --verboseEach binding and bucket line ends in
ok. The warnings are about size limits. You can ignore them in this tutorial.
3. Start the gateway
On a licensed build, first set MQGW_LICENSE_FILE to the path of your
license file. Then start the gateway:
./mq-gateway --config gateway.yaml
The log ends with msg="account ready". Keep the gateway running.
4. Publish at QoS 1
-
Publish an alarm:
mqttx pub -h 127.0.0.1 -q 1 -t 'plant1/line3/press7/alarms' -m 'pressure low'MQTTX prints
Message published. The gateway acknowledges the publish only after the stream stores the message. -
Read the message from the stream:
nats stream get ALARMS 1The output shows the subject
plant1.line3.press7.alarmsand the payloadpressure low. -
Publish at QoS 1 to a topic that no binding stores:
mqttx pub -h 127.0.0.1 -q 1 -t 'plant1/line3/press7/telemetry' -m '48.5C'The gateway refuses the publish. MQTTX prints
Publish error: Implementation specific error.
5. Subscribe at QoS 2
-
Subscribe:
mqttx sub -h 127.0.0.1 -q 2 -t 'plant1/+/+/alarms' -
In a new terminal, publish at QoS 2:
mqttx pub -h 127.0.0.1 -q 2 -t 'plant1/line3/press7/alarms' -m 'overtemp'The subscriber prints
overtempwithqos: 2. -
List the consumers of the stream:
nats consumer ls ALARMSThe subscriber's session has one consumer.
-
Stop the subscriber with Ctrl-C.
6. Retain a message
-
Publish with the retain flag:
mqttx pub -h 127.0.0.1 -r -t 'plant1/line3/press7/telemetry' -m '48.5C'This topic needs no binding. The retained bucket stores the message:
nats kv ls MQTT_RETAINEDThe output is
plant1.line3.press7.telemetry. -
Subscribe after the publish:
mqttx sub -h 127.0.0.1 -t 'plant1/+/+/telemetry'The subscriber prints
48.5Cwithretain: true. -
Stop the subscriber.
7. Keep a session across a restart
-
Subscribe as client
hmi-1with a persistent session of one hour:mqttx sub -h 127.0.0.1 -q 1 -t 'plant1/+/+/alarms' -i hmi-1 --no-clean -se 3600 -
Stop the subscriber with Ctrl-C.
-
Publish an alarm while
hmi-1is away:mqttx pub -h 127.0.0.1 -q 1 -t 'plant1/line3/press7/alarms' -m 'while away' -
Stop the gateway with Ctrl-C. Then start it again:
./mq-gateway --config gateway.yaml -
Connect
hmi-1again with the command from item 1.The subscriber prints
while away. The gateway that held the session stopped, but NATS kept the session in the bucketMQTT_SESSIONS. Its consumer kept the alarm. -
Stop all processes with Ctrl-C. To remove the stored data, remove the
./js-datadirectory.
Next steps
- Provision the streams and buckets with limits for production.
- Config file.
- How it works.