Introducing QtMqtt

Recently, we talked about how we're broadening our offering towards the automation sector. In case you missed it, you can find all relevant information here as well as read our blog post here.

One of the biggest challenges in starting an automation project is to build a suitable communication stack. MQTT has received more and more popularity over the last years for managing telemetry data (i.e. collecting data from sensors, health status of devices etc.). This is why we are now extending our portfolio to further help and simplify the development workflow.

What is MQTT

MQTT describes itself as follows:

"It was designed as an extremely lightweight publish/subscribe messaging transport. It is useful for connections with remote locations where a small code footprint is required and/or network bandwidth is at a premium."

Using a publisher-subscriber methodology puts the routing responsibility towards the server (or in this context called "message broker"), which all clients connect to. Multiple levels of service quality can be specified to guarantee message delivery.

The connection itself usually builds on top of a TCP connection. However, it can use any ordered, lossless and bi-directional communication method.

How QtMqtt Fits Into the Picture

QtMqtt is a client implementation, which can be used for creating devices to send, but also to monitor solutions for receiving and managing data. QtMqtt does not focus on the broker side.

One important item to mention is that we aim to have QtMqtt fully specification compliant compared to other solutions. This implies support for

  • Protocol level 3.1 and 3.1.1 (prominently known/referred as 4)
  • All QoS levels
  • Wildcards
  • Authentication
  • SSL connections
  • Last Will support

Let 's dig a bit deeper and discuss how you actually use QtMqtt in your project.

Publishing data:

QMqttClient publisher;
publisher.setHostname(“some.brokerlocation.com”);
publisher.setPort(1883);
publisher.connectToHost();

publisher.publish(“sensor_1/dataset/foo”, “values”, qosLevel);

Receiving data:
QMqttClient subscriber;
subscriber.setHostname(“some.brokerlocation.com”);
subscriber.setPort(1883);
subscriber.connectToHost();
. . .
QSharedPointer<QMqttSubscription> sub = subscriber.subscribe(“sensor_1/#”, qosLevel);
connect(sub.data(), &QMqttSubscription::messageReceived, [&](QMqttMessage msg) {
qDebug() << “New Message:” << msg.payload();
});

Security

It is crucial for any automation solution today to make sure that all communication is secure and safe. QtMqtt provides two means to achieve this:

  1. Authentication via username and password when a connection is established.
  2. Using SSL/TLS sockets as connection channel.

For the latter case, we can utilize QSslSocket as provided by Qt Network. As a convenience, QMqttClient has another member called connectToHostEncrypted() which behaves similar to QSslSocket's argument list.

Extending QtMqtt

While MQTT is mostly used via TCP, it isn't hardwired to it. QtMqtt allows you to specify additional transport methods, which are based on either QIODevice or QAbstractSocket. This implies that you can create your own transport and pass it over to QMqttClient before establishing a connection.

One concrete example is to use MQTT over websockets, for which Qt provides a separate module. QWebsocket is not based on QAbstractSocket due to different means of sending and receiving data. However, the specification is very clear on how MQTT data has to be pushed via websocket (send as binary data, must fit one datagram, etc.). Hence, a convenience class can be implemented. The specific showcase can be found in the examples of the QtMqtt module.

If you found this post interesting, feel free to get in touch with us and get access to a prerelease version.


Blog Topics:

Comments