MQTT Client Library Encyclopedia - Mosquitto-PHP
Written by Michael Maclean
Category: MQTT MQTT Client Library
Published: August 31, 2015
|License||New BSD license|
|API Style||Blocking, with callbacks|
The Mosquitto-PHP library is a wrapper for the client library from the Mosquitto MQTT broker. As such, it implements most of the features in the MQTT 3.1.1 specification. It has been around since around 2013, and is currently in beta. It works with PHP version 5.3 and greater, though not yet PHP 7, and with Mosquitto version 1.3 and above. The source is held on Github, and contributions are always welcome.
The library uses Mosquitto’s event loop to handle messages. You’ll construct a new client instance, set some callbacks to handle the various events, and then enter the event loop.
First off, you’ll need to make sure you have the Mosquitto client library installed, along with its development package. The extension requires version 1.3 or higher. On Linux, this can be compiled from source, or there are some pre-built packages available.
- On Ubuntu there is a PPA for the latest version here. The package name you’ll need is libmosquitto-dev.
- Fedora users should be able to install straight away. The package name you want is mosquitto-devel.
- Mac OS X users can install Mosquitto using Homebrew: brew install mosquitto
The easiest way to install the PHP extension itself is to use PECL. On Linux and OSX, you can just type
pecl install Mosquitto-alpha
This will download the latest version of the package from Github, compile it, and install it. Finally, you may need to add the following to php.ini:
Now, you should be all set!
To connect to the broker, you’ll need something like the following code.
In this code, we construct a new client instance, and set a callback for the onMessage event fired when the client connects successfully (receiving a CONNACK message from the broker). In the code above, we pass an anonymous function, but this can be any PHP callable so you can use normal functions or object methods.
When the onConnect callback is fired, we subscribe to the broker’s $SYS namespace, which contains some monitoring information – sufficient for a demonstration. We then specify the onMessage callback, which in this case just prints the topic and the payload of each message to the console.
Finally, we connect to the broker, and enter the event loop. The loopForever() method is a convenience method that loops around and handles events on its own, but if you want more control you can do the event handling yourself using the loop() method.
If you run the code above, you should see some statistics returned from the HiveMQ public broker.
Connect with LWT
It’s possible to supply a Last-Will-and-Testament message, which will be sent by the broker in the event that your client connection goes away without disconnecting cleanly. You must specify this before connecting.
In this code, we set a LWT to be sent on the topic my/will/topic, with the payload My will payload, a QoS value of 1, and the final true indicates that the message should be retained.
If you wish to remove a LWT that you have previously set, you can use the clearWill() method:
Connect with Username / Password
If your broker requires authentication, you can supply a username and password before calling connect(), by using the setCredentials() method:
Once connected, you can publish messages with the publish() method. It takes the following parameters:
$client->publish($topic, $payload, $qos, $retain);
The topic and the payload are required. The QoS is an integer value – 0, 1 or 2. If not specified, the QoS will default to 0 and the message will not be retained.
Publish a retained message
To publish a message with QoS 1 and have it retained, you can use the fourth parameter to publish():
$client->publish('my/topic', 'My retained message payload', 1, true);
You can subscribe to topics with the subscribe() method.
$messageId = $client->subscribe($topic, $qos);
Currently, both the parameters are required. This method returns the message ID of the subscription request. There is a corresponding onSubscribe callback, which is triggered when a subscription has been successful.
Worth noting is that messages for all subscribed topics run through the same onMessage callback. If you need to handle different topics in different ways, you will need to implement that yourself.
Unsubscribing is simple. Just use the unsubscribe() method:
$messageId = $client->unsubscribe($topic);
Again, this will return the message ID of the unsubscription request, which can be useful for accounting purposes. Again, there is an onUnsubscribe callback, triggered on a successful unsubscribe request.
To disconnect from the broker, simply call disconnect():
If you’re using loopForever(), the client will not exit the loop until all the messages required for a clean disconnection have been passed, at which point it will return. There is an onDisconnect() callback which will be triggered when the disconnection is complete. If you are using loopForever(), the loop will exit at this point.
Using TLS / SSL
Mosquitto-PHP provides full support for using TLS to connect to brokers. It can use the traditional certificate-based authentication, or use TLS pre-shared keys (PSK) if the broker supports it. Finally, it also supports using client certificates for authenticating to the broker.
Validating the server certificate The most basic mode is to verify that the broker’s TLS certificate is trusted by a known certificate authority. To do this, you can supply the path to the CA certificate file, or to a directory containing them:
This must be done before calling connect().
Using a client certificate Additionally, you can supply a client certificate in order to identify your client to the broker. These are additional parameters to setTlsCertificates(). You must also supply the path to the private key for the client certificate, and the passphrase for the key if it’s encrypted.
Using TLS pre-shared keys Some brokers support TLS PSK, which is a recent addition to the standard. To use this, you use the setTlsPSK() method.
The first parameter is the key, in hex format, but with the leading 0x removed. The second parameter is the identity to use, which will correspond to one configured on the server.
The code below will subscribe to a list of topics, with a given QoS value for each topic, and record every message in a MySQL database. It contains a class, which is handed a pre-connected Client instance and a DB connection. These are configured outside of the class to avoid having to deal with the intricacies of setting up the connections. In the class constructor, it sets the onConnect and onMessage callbacks to its own methods: the onConnect callback handles subscribing to the topics requested by the user, and onMessage handles inserting the data into a database using a prepared statement.
The database table structure is as below.
The code is as follows.