I’m almost at the end of implementing the changes to the Eclipse Paho C client that I described in an earlier post to support MQTT 5.0. I haven’t quite finished off the release yet, so I thought I’d allow a little more time for anyone to comment. I had to compromise in my naming of the APIs for MQTT 5.0 support; none of the proposals I created were perfect, so I’m particularly interested in any feedback in that area.
MQTT 5.0 is not the only change for this release of the C client, but it is the biggest. You can find the complete list in the milestone. Another major addition is WebSocket support, thanks to the contribution of Keith Holman.
Another improvement I’ve been able to make is the update of the command line utilities. Back in 2010, I called them stdinpub and stdoutsub, the idea being that they could be used in Unix pipe combinations. Stdinpub reads data from stdin and publishes the results to an MQTT server; stdoutsub subscribes to an MQTT server and sends the data to stdout. I hadn’t really touched these programs in the meantime except to change the names to paho_c_pub and paho_c_sub. I always had intended to add TLS and other functionality to make them comparable to the Eclipse Mosquitto utilities mosquitto_pub and mosquitto_sub.
Now I’ve actually done that (small cheer!). Along with TLS I’ve added support for WebSockets and of course, MQTT 5.0. In each case, I have followed the Mosquitto utilities options where possible, so that it should be easy to switch from one to the other. There are actually two versions of each, one for each style of Paho C library, MQTTClient and MQTTAsync:
- paho_c_pub – MQTTAsync C publisher
- paho_c_sub – MQTTAsync C subscriber
- paho_cs_pub – MQTTClient C publisher
- paho_cs_sub – MQTTClient C subscriber
As well as being a useful way to experiment with V5 support, they also serve as examples on how to use the various APIs, for instance, how to write an application which combines support for all MQTT versions. You can try the following examples of using the command line utilities against the Paho test broker which supports all the combinations needed: WebSockets, MQTT 5.0 and TLS. To to start it up:
git clone firstname.lastname@example.org:eclipse/paho.mqtt.testing.git cd git/paho.mqtt.testing/interoperability python3 startbroker.py -c localhost_testing.conf
Typing paho_c_pub on the command line will display the option help:
-t (--topic) : MQTT topic to publish to -c (--connection) : connection string, overrides host/port e.g wss://hostname:port/ws. Use this option rather than host/port to connect with TLS and/or web sockets. No default. -h (--host) : host to connect to. Default is localhost. -p (--port) : network port to connect to. Default is 1883. -q (--qos) : MQTT QoS to publish with (0, 1 or 2). Default is 0. -V (--MQTTversion) : MQTT version (31, 311, or 5). Default is 311. --quiet : do not print error messages. --trace : print internal trace ("error", "min", "max" or "protocol"). -r (--retained) : use MQTT retain option. Default is off. -n (--null-message) : send 0-length message. -m (--message) : the payload to send. -f (--filename) : use the contents of the named file as the payload. -i (--clientid) : MQTT client id. Default is paho-c-pub. -u (--username) : MQTT username. No default. -P (--password) : MQTT password. No default. -k (--keepalive) : MQTT keepalive timeout value. Default is 10 seconds. --delimiter : delimiter string. Default is \n. --maxdatalen : maximum length of data to read when publishing strings (default is 100) --message-expiry : MQTT 5 only. Sets the message expiry property in seconds. --user-property : MQTT 5 only. Sets a user property. --will-topic : will topic on connect. No default. --will-payload : will message. If the will topic is set, but not payload, a null message will be set. --will-retain : set the retained flag on the will message. The default is off. --will-qos : the will message QoS. The default is 0. --cafile : a filename for the TLS truststore. --capath : a directory name containing TLS trusted server certificates. --cert : a filename for the TLS keystore containing client certificates. --key : client private key file. --keypass : password for the client private key file. --ciphers : the list of cipher suites that the client will present to the server during the TLS handshake. --insecure : don't check that the server certificate common name matches the hostname.
Here are some examples of use. To publish to the test broker on localhost over WebSockets using MQTT 5.0:
paho_c_pub -t topic --connection ws://localhost:1883 -V 5
To subscribe to the test broker on localhost over WebSockets with TLS server authentication using MQTT 3.1.1 by default:
paho_c_sub -t topic --connection wss://localhost:18885 --cafile test/ssl/test-root-ca.crt
And with mutual authentication without WebSockets:
paho_c_pub x --connection ssl://localhost:18884 --cafile test/ssl/test-root-ca.crt --cert test/ssl/client.pem --trace protocol
The –trace option displays various levels of trace, for debugging. A particularly useful level is ‘protocol’, which displays the MQTT and OpenSSL exchanges:
paho_c_pub x --connection ws://localhost:1883 -V 5 --trace protocol Trace : 3, ========================================================= Trace : 3, Trace Output Trace : 3, Product name: Eclipse Paho Asynchronous MQTT C Client Library Trace : 3, Version: 1.2.1 Trace : 3, Build level: 2018-08-06T19:00:57Z Trace : 3, OpenSSL version: OpenSSL 1.0.2o 27 Mar 2018 Trace : 3, OpenSSL flags: compiler: clang -I. -I.. -I../include -fPIC -fno-common -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -arch x86_64 -O3 -DL_ENDIAN -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM Trace : 3, OpenSSL build timestamp: built on: reproducible build, date unspecified Trace : 3, OpenSSL platform: platform: darwin64-x86_64-cc Trace : 3, OpenSSL directory: OPENSSLDIR: "/usr/local/etc/openssl" Trace : 3, ========================================================= Trace : 4, 20180809 144216.424 Connecting to serverURI localhost:1883 with MQTT version 5 Trace : 4, 20180809 144216.525 WebSocket connection upgraded Trace : 4, 20180809 144216.525 5 paho-c-pub -> CONNECT cleansession: 0 (0) Trace : 4, 20180809 144216.528 5 paho-c-pub <- CONNACK rc: 0 dfsdf Trace : 4, 20180809 144259.493 5 paho-c-pub -> PUBLISH qos: 0 retained: 0 (0)
If using MQTT 5.0, you can attach user and message expiry properties to the sent message:
paho_c_pub -t topic --connection ws://localhost:1883 -V 5 --user-property name value --message-expiry 55
when received can be displayed with the –verbose option:
paho_c_sub x -V 5 -v URL is localhost:1883 Subscribing to topic x with client paho-c-sub at QoS 0 13 x dadasd Property name MESSAGE_EXPIRY_INTERVAL value 55 Property name USER_PROPERTY key name value value
These utilities now have man pages too, as does the API itself, so I’ll have to make sure those are installed appropriately.