mqtt

Portable MQTT 5.0 client implementation:

https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html

This initial version provides the client-side MQTT transport and packet handling using objects that implement the http_transport_protocol protocol. It supports MQTT and MQTT-over-TLS connections, performs the MQTT 5.0 CONNECT/CONNACK exchange, provides packet encoding and decoding predicates, and implements synchronous publish, subscribe, unsubscribe, receive, and ping operations.

This library can be used with backend Prolog systems that support both unbound integer arithmetic and the sockets library: ECLiPSe, SICStus Prolog, SWI-Prolog, Trealla Prolog, and XVM.

API documentation

Open the ../../apis/library_index.html#mqtt link in a web browser.

Loading

To load this library, load the loader.lgt file:

| ?- logtalk_load(mqtt(loader)).

Testing

To test this library predicates, load the tester.lgt file:

| ?- logtalk_load(mqtt(tester)).

Transport Selection

The connect/3 predicate accepts mqtt://Host[:Port] and mqtts://Host[:Port] addresses. The default port is 1883 for mqtt and 8883 for mqtts.

The transport(default) option follows the HTTP libraries design:

  • mqtt uses http_socket_transport.

  • mqtts uses http_process_transport.

  • mqtts adds connection_transport(tls) to connection options unless a connection transport is already specified explicitly.

Applications can pass any object implementing http_transport_protocol using the transport/1 option.

Current Status

This library currently provides a client-only MQTT 5 API. The connect/3 and connect/4 predicates open a transport connection and wait for a successful CONNACK packet before returning. A non-success CONNACK reason code closes the transport connection and throws an error.

The publish/4, subscribe/4, and unsubscribe/4 predicates are synchronous:

  • QoS 0 publish/4 writes the PUBLISH packet and returns.

  • QoS 1 publish/4 waits for the matching PUBACK packet.

  • QoS 2 publish/4 waits for PUBREC, sends PUBREL, and waits for PUBCOMP.

  • subscribe/4 waits for the matching SUBACK packet and returns its reason codes.

  • unsubscribe/4 waits for the matching UNSUBACK packet and returns its reason codes.

The send_pingreq/1 predicate sends a PINGREQ packet. The ping/2 predicate sends PINGREQ and waits synchronously for PINGRESP. The receive/3 predicate reads and decodes the next MQTT packet.

The disconnect/2 predicate sends a normal DISCONNECT packet and then closes the transport connection.

The public encode_packet/2 and decode_packet/2 predicates support the current normalized packet terms for CONNECT, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, PINGREQ, PINGRESP, DISCONNECT, and AUTH packets.

Limitations

The implementation is intentionally synchronous and client-only. It does not run a background receive loop, does not maintain an incoming message queue, and does not automatically send keep-alive pings. Applications should call receive/3, send_pingreq/1, or ping/2 explicitly as needed.

MQTT 5 property encoding and decoding supports all MQTT 5 property identifiers using normalized property terms in packet properties/1 fields. This includes user properties, authentication method and data, topic aliases, subscription identifiers, response topics, correlation data, payload format indicators, message expiry, session expiry, and receive maximum values. Property order is preserved, and repeated user properties are supported.

The CONNECT packet currently supports client identifier, clean start, keep alive, and properties. Will messages, username/password authentication, enhanced authentication flow, topic alias state management, property context validation, duplicate single-use property validation, and session state management are not yet implemented.

QoS acknowledgement handling checks the expected packet type and packet identifier. It does not maintain persistent in-flight state across calls or recover QoS exchanges after a connection loss.

Packet payloads and binary fields are represented as lists of byte values. MQTT UTF-8 strings are represented as atoms and are checked for null characters; full Unicode well-formedness checks beyond the backend atom/code conversion are not currently implemented.