14 September, 2018

MQTT.js client library upgraded to MQTT 5.0 standard

Javascript MQTT client library enriched with all features from the MQTT 5.0 specification.

MQTT.js Javascript library is now MQTT 5.0 ready. It runs in any browser and in Node.js (including the latest version 10). MQTT.js is open-source with Sergey from the flespi team being the major contributor to making it MQTT 5.0 compliant. flespi is an active promoter of the MQTT 5.0 standard having released the first MQTT 5.0 broker to the market and now supplying the web dev community with new opportunities provided by MQTT.js with the 5.0 support. In this article, we will briefly go through the major features and distinctions of the latest specification and give code samples for the basic actions.

We will not reiterate the entire set of features, since you can find them in the MQTT.js docs, and will only focus on what MQTT 5.0 brought to the table.

Installation

Make sure you have node.js installed. Then install MQTT.js:

npm install mqtt

If you also need the embedded CLI tools, use

npm install mqtt -g

Connect

mqtt.connect([url], options)

Connects to the broker at the given URL and options and returns a client.

The following protocols are supported: 'mqtt', 'mqtts', 'ws', 'wss'. The URL can also be an object as returned by URL.parse() — then two objects are merged, i.e. you can pass a single object with both the URL and the options. If you are connecting from web-browser then you have to use 'wss' or 'wss' protocol (it is based on web sockets browser feature). If you are connecting from a server, e.g. node.js you may use any of supported protocols as there is usually no restrictions on establishing raw TCP connections between servers.

You can also specify the server options like this: [{ host: 'localhost', port: 1883 }, ... ]. Such an array will be iterated upon every connect. Here is the sample for connecting to flespi MQTT broker from server, using direct TCP connection protected by SSL ('mqtts' protocol):

var mqtt    = require('mqtt');
var client  = mqtt.connect('mqtts://mqtt.flespi.io:8883', {
  username: 'FlespiToken XXXXXXXXXXXXXXXXXXXXXXXXX'
});

Connect with MQTT 5.0 using flespi token

You can connect to the flespi MQTT broker using a unique flespi token. To generate one, log in with the flespi panel, go to the Tokens in the left-side menu, and click the “+” sign. You may read more about flespi tokens here.

The library connects with MQTT 3.1.1 by default. To connect with MQTT 5.0 and the generated token from web browser use 'wss' protocol:

var mqtt    = require('mqtt');
var client  = mqtt.connect('wss://mqtt.flespi.io',{
  protocolVersion: 5,
username: 'FlespiToken XXXXXXXXXXXXXXXXXXXXXXXXX'
});

Connect with Last Will & Testament (LWT)

Last Will & Testament in MQTT is the possibility to be ‘courteous’ to the subscribers by returning them a special message instead of vanishing in case of unexpected disconnect or other issues. In practice, LWT is often used together with retained messages to store the state of a client on a specific topic.

LWT can be set in the connect function like this:

var mqtt    = require('mqtt');
var client  = mqtt.connect('wss://mqtt.flespi.io',{
  will: {
    topic: 'lost',
    payload; 'somepayload',
    qos: 1,
    retain: true,
    properties: {
    willDelayInterval: 120 /* MQTT 5.0 property saying how many seconds to wait before publishing the LWT message */
  }
  },
  username: 'FlespiToken XXXXXXXXXXXXXXXXXXXXXXXXX'
});

Publish

mqtt.Client#publish(topic, message, [options], [callback])

A function to publish a message to a topic. Here are the novelties brought by MQTT 5.0:

  • properties: MQTT 5.0 properties object

    • payloadFormatIndicator: whether the payload is UTF-8 or not (boolean),

    • messageExpiryInterval: the lifetime (number) of the Application Message in seconds,

    • topicAlias: a topic identifier (number) used  instead of Topic Name,

    • responseTopic: a string used as the Topic Name in the response message,

    • correlationData: used by the sender of the Request Message to identify which request the Response Message is for when it is received (binary),

    • userProperties: a custom user property can appear multiple times to represent multiple name/value pairs (object),

    • subscriptionIdentifier: a value (number) representing the identifier of the subscription,

    • contentType: a string determining the content of the Application Message.

Subscribe

mqtt.Client#subscribe(topic/topic array/topic object, [options], [callback])

A function to subscribe to a topic or topics. Here’s the new functionality since MQTT 5.0:

  • options: subscription options:

    • nl: No Local (boolean). If true, Application Messages MUST NOT be forwarded to a connection with a ClientID equal to the ClientID of the publishing connection.

    • rap: Retain as Published (boolean). If true, Application Messages forwarded using this subscription keep the RETAIN flag they were published with. If false, Application Messages forwarded using this subscription get the RETAIN flag set to 0.

    • rh: Retain Handling (integer). This option specifies whether retained messages are sent when the subscription is established. Values 0,1, and 2 are accepted.

    • properties: object

      • subscriptionIdentifier: a value (number) representing the identifier of the subscription,

      • userProperties: a custom user property can appear multiple times to represent multiple name/value pairs (object).

client.on('message', function (topic, message, packet) {
/* message is Buffer */
console.log(message.toString());
console.log(packet.properties.userProperties);
client.end();
});
client.subscribe('flespi/state/#');

Note: a packet parameter contains the entire message with all custom properties. flespi also includes the message timestamp into this parameter by default.

Unsubscribe

mqtt.Client#unsubscribe(topic/topic array, [options], [callback])

A function to unsubscribe from a topic or topics.

  • options: options for an unsubscribe.
    • properties: object
      • userProperties: a custom user property can appear multiple times to represent multiple name/value pairs (object).

Close connection or stop

mqtt.Client#end([force], [options], [cb])

A function to close the client. Here's the MQTT 5.0 stuff:

  • options: options for a disconnect.
    • reasonCode: a number representing a disconnect Reason Code,
    • properties: object
      • sessionExpiryInterval: a value in seconds representing the Session Expiry Interval,
      • reasonString: a reason for the disconnect,
      • userProperties: a custom user property can appear multiple times to represent multiple name/value pairs (object),
      • serverReference: a string that can be used by the Client to identify another Server to use,
      • cb: [optional] will be called when the client is closed.

Troubleshooting

If you experience issues connecting to the MQTT broker, consider adding a piece of code to print errors to the browser console (see the part under the comment):

var mqtt    = require('mqtt');
var client  = mqtt.connect('wss://mqtt.flespi.io',{
  protocolVersion: 5,
username: 'FlespiToken XXXXXXXXXXXXXXXXXXXXXXXXX'
});

/* output error to console */
client.on('error', function (error) {
console.log(error)
})

Examples

We have written nice and neat MQTT client examples in several popular programming languages to speed up your onboarding with MQTT. You are welcome to contribute your examples in other languages.

Extras

The following useful libraries have also been brought up to date with the latest MQTT 5.0 specification:

mqtt-packet: a JS library to encode and decode the MQTT 3.1.1, 5.0 packets the node way.

mqtt-connection: a barebone Connection object for MQTT that works over any kind of binary Streams, TCP, TLS, WebSocket, etc.

***

We do believe in the bright future of MQTT protocol in the IoT applications as a more performant and light-weight alternative to HTTP and work on providing the developers' community with the necessary tools for maximally efficient application creation. Give it a try and share your impressions with us.