Overview
mosquitto wraps Eclipse Mosquitto's libmosquitto — the reference C client library for MQTT 3.1.1 and 5.0. MQTT is a lightweight publish/subscribe protocol designed for constrained devices and unreliable networks, widely used in IoT sensors, home automation, fleet telemetry, and real-time dashboards.
The package exposes a simple Pascal API: connect to any broker, publish messages with QoS guarantees, subscribe to topic filters using wildcards, and receive messages via a blocking WaitMessage call or a non-blocking drain loop — all with optional TLS and authentication.
Ubuntu/Debian: sudo apt install libmosquitto-dev
Quick Start
Publisher
uses mosquitto;
LibInit;
var client := NewClient('publisher-1', True);
Connect(client, 'mqtt.example.com', 1883, 60);
StartLoop(client);
{ Publish sensor readings }
Publish(client, 'sensors/room1/temp', '22.5', qos1, False);
Publish(client, 'sensors/room1/humidity', '65', qos1, False);
Disconnect(client);
StopLoop(client);
DestroyClient(client);
LibCleanup;
Subscriber loop
uses mosquitto;
LibInit;
var client := NewClient('subscriber-1', True);
Connect(client, 'mqtt.example.com', 1883, 60);
StartLoop(client);
Subscribe(client, 'sensors/+/temp', qos1);
Subscribe(client, 'alerts/#', qos2);
while True do
begin
var msg := WaitMessage(client, 5000);
if msg.Topic <> '' then
WriteLn('[' + msg.Topic + '] ' + msg.Payload);
end;
Lifecycle API
Initialize the library once per process, create per-connection client handles, and clean up when done.
| Function | Description |
|---|---|
| LibInit | Initialize the libmosquitto library. Must be called once before any other mosquitto function. |
| LibCleanup | Release all resources held by the library. Call once at program exit after all clients are destroyed. |
| NewClient(id, cleanSession) | Create a new MQTT client handle. id is the client identifier string; cleanSession determines whether the broker discards session state on reconnect. |
| DestroyClient(client) | Free all memory associated with a client handle. Must be called after Disconnect and StopLoop. |
Connection API
| Function | Description |
|---|---|
| Connect(client, host, port, keepalive) | Connect to an MQTT broker at host:port. keepalive is the interval in seconds between PINGREQ packets sent to the broker. |
| ConnectEx(client, opts) | Connect using a TMQTTConnectOptions record for full control over host, port, keepalive, TLS, credentials, and Last Will in one call. |
| Reconnect(client) | Reconnect using the same parameters as the last Connect call. Useful after a network drop is detected. |
| Disconnect(client) | Send a DISCONNECT packet to the broker and close the connection cleanly. |
| IsConnected(client) | Returns True if the client currently has an active connection to the broker. |
Publish API
| Function | Description |
|---|---|
| Publish(client, topic, payload, qos, retain) | Publish a UTF-8 string payload to topic with the specified QoS level (qos0, qos1, qos2) and optional retain flag. |
| PublishBytes(client, topic, data, len, qos, retain) | Publish a raw byte buffer of len bytes. Use for binary payloads such as Protobuf, MessagePack, or sensor frames. |
Subscribe API
| Function | Description |
|---|---|
| Subscribe(client, topicFilter, qos) | Subscribe to a single topic filter. Supports + (single-level) and # (multi-level) wildcards. The broker delivers messages at the negotiated QoS. |
| SubscribeMany(client, filters, qos) | Subscribe to a List<String> of topic filters in a single network round-trip. |
| Unsubscribe(client, topicFilter) | Remove an existing subscription. The broker stops delivering messages for that filter immediately. |
Message Loop API
libmosquitto requires a background network loop to process incoming packets, send outgoing messages, and maintain keepalives. Use StartLoop/StopLoop for a background thread, or drive the loop manually with LoopOnce.
| Function | Description |
|---|---|
| StartLoop(client) | Start a background thread that continuously calls the internal network loop. Non-blocking; returns immediately. |
| StopLoop(client) | Signal the background loop thread to stop and wait for it to exit. Call before DestroyClient. |
| LoopOnce(client, timeout) | Perform a single iteration of the network loop, blocking for up to timeout milliseconds. Use when you manage your own event loop. |
| WaitMessage(client, timeoutMs) | Block until a message arrives on any subscribed topic or timeoutMs elapses. Returns a TMQTTMessage record; check Topic <> '' to detect a real message vs. timeout. |
| DrainMessages(client) | Collect all messages currently queued in the receive buffer and return them as a List<TMQTTMessage> without blocking. |
Last Will Testament
A Last Will Testament (LWT) is a message the broker automatically publishes on a designated topic if the client disconnects unexpectedly (network drop, crash, or keepalive timeout). Set it before calling Connect or ConnectEx.
uses mosquitto;
LibInit;
var client := NewClient('sensor-node-42', True);
{ Register LWT before connecting }
SetLastWill(client,
'devices/sensor-node-42/status', { topic }
'offline', { payload }
qos1, { QoS }
True { retain — broker keeps last value }
);
Connect(client, 'mqtt.example.com', 1883, 60);
StartLoop(client);
{ Announce online }
Publish(client, 'devices/sensor-node-42/status', 'online', qos1, True);
{ ... normal operation ... }
Disconnect(client); { clean disconnect — LWT is NOT published }
StopLoop(client);
DestroyClient(client);
LibCleanup;
The LWT is only published by the broker on an abnormal disconnect. A clean Disconnect() call suppresses it. This makes LWT ideal for presence tracking and device health monitoring.
TLS & Auth
Call TLS and credential functions before Connect. TLS functions configure the underlying OpenSSL context used by libmosquitto.
| Function | Description |
|---|---|
| SetTLS(client, caFile, caPath) | Enable TLS using a CA certificate file or directory. The broker's certificate chain is verified against this CA. Pass '' for unused parameter. |
| SetTLSMutual(client, caFile, certFile, keyFile, keyPassword) | Enable mutual TLS (mTLS): the client presents its own certificate. Required by brokers that enforce client-side certificate authentication. |
| SetCredentials(client, username, password) | Set the MQTT username and password sent in the CONNECT packet. Used with brokers that enforce ACL-based access control. |
var client := NewClient('secure-client', True);
{ One-way TLS — verify broker certificate }
SetTLS(client, '/etc/ssl/certs/ca-certificates.crt', '');
SetCredentials(client, 'myuser', 's3cr3t');
Connect(client, 'mqtt.example.com', 8883, 60); { port 8883 = MQTT over TLS }
{ Mutual TLS — broker verifies client certificate too }
SetTLSMutual(client,
'/certs/ca.crt',
'/certs/client.crt',
'/certs/client.key',
'' { key password, empty if unencrypted }
);
Connect(client, 'broker.internal', 8883, 30);
Key Concepts
+ matches exactly one level: sensors/+/temp matches sensors/room1/temp but not sensors/a/b/temp.# matches any number of levels and must be the last segment: alerts/# matches alerts/fire, alerts/fire/zone2, etc.
qos1 — at least once. Message acknowledged; may be delivered multiple times.
qos2 — exactly once. Four-way handshake guarantees no duplicates. Highest overhead.
retain = True, the broker stores the last published value for a topic. New subscribers immediately receive the retained message on connect — useful for device state and configuration topics.
Disconnect.
Broker examples
The mosquitto package works with any MQTT 3.1.1-compatible broker. Popular choices:
| Broker | Notes |
|---|---|
| Eclipse Mosquitto | Lightweight, open source. Ideal for self-hosting. sudo apt install mosquitto. |
| HiveMQ | Enterprise-grade, cloud or on-premises. Free Community Edition available. |
| EMQX | High-throughput, clustering, rule engine. Popular for large IoT deployments. |
| AWS IoT Core | Managed cloud broker. Endpoint: xxxxxxxxxxxxxx.iot.us-east-1.amazonaws.com:8883 (mTLS required). |
| test.mosquitto.org | Public test broker (no auth, no TLS). Port 1883. Suitable for development only. |
TMQTTConnectOptions
Use ConnectEx with a TMQTTConnectOptions record for full control in a single call. Fields not set default to safe values.
type TMQTTConnectOptions = record
Host : String; { broker hostname or IP }
Port : Integer; { default 1883; use 8883 for TLS }
KeepAlive : Integer; { seconds between PINGREQs, default 60 }
ClientId : String; { unique client identifier }
CleanSession: Boolean; { True = discard session on disconnect }
Username : String; { empty = no authentication }
Password : String;
UseTLS : Boolean; { enable TLS/SSL }
CAFile : String; { path to CA certificate file }
CertFile : String; { client certificate for mTLS }
KeyFile : String; { private key for mTLS }
LWTTopic : String; { Last Will topic; empty = no LWT }
LWTPayload : String;
LWTQoS : Integer; { 0/1/2 }
LWTRetain : Boolean;
end;
ConnectEx example
uses mosquitto;
LibInit;
var client := NewClient('fleet-tracker-7', True);
var opts: TMQTTConnectOptions;
opts.Host := 'broker.internal';
opts.Port := 8883;
opts.KeepAlive := 30;
opts.CleanSession := True;
opts.Username := 'tracker';
opts.Password := 'fleet-secret';
opts.UseTLS := True;
opts.CAFile := '/certs/ca.crt';
opts.LWTTopic := 'fleet/tracker-7/status';
opts.LWTPayload := 'offline';
opts.LWTQoS := 1;
opts.LWTRetain := True;
ConnectEx(client, opts);
StartLoop(client);
Publish(client, 'fleet/tracker-7/status', 'online', qos1, True);
Publish(client, 'fleet/tracker-7/gps', '{"lat":40.7128,"lon":-74.006}', qos1, False);
Disconnect(client);
StopLoop(client);
DestroyClient(client);
LibCleanup;
Package Info
TMQTTMessage
.Topic — topic string.Payload — message payload.QoS — delivery QoS (0/1/2).Retain — True if retained.MessageId — broker message ID
QoS Constants
qos1 — at least once
qos2 — exactly once
Functions
- LibInit / LibCleanup
- NewClient / DestroyClient
- Connect / ConnectEx
- Reconnect / Disconnect
- IsConnected
- Publish / PublishBytes
- Subscribe / SubscribeMany
- Unsubscribe
- StartLoop / StopLoop
- LoopOnce
- WaitMessage
- DrainMessages
- SetLastWill
- SetTLS / SetTLSMutual
- SetCredentials