MQTT Client Library Encyclopedia – mqtt-elements

Guest post by Sandro Kock

<mqtt-elements>
LanguageJavascript
LicenseMIT
Websitehttps://github.com/mqttjs/mqtt-elements
API Styledeclarative

Description

<mqtt-elements> are Web Components build on top of MQTT.js to expose the mqtt functionality as a custom HTML-Element. Web Components enable a new way of web development where different parts of a Web-Application are encapsulated and re-usable. These custom elements are build using HTML and JavaScript to extend the functionality of HTML itself. All <mqtt-elements> are build using the Polymer 1.0 library that adds a lightweight sugaring layer to make the development of complex Web Components easier.

The first beta release of <mqtt-elements> was just about a month ago on 09/02/15, so it can be considered a relatively early stage project. But building on top of the highly tested MQTT.js library compatibility issues are unlikely.

<mqtt-elements> and the browserifyed version of MQTT.js are feature equivalent and everything that can be done with MQTT.js can be done with <mqtt-elements>. Currently the main focus of the project is to extend the test coverage of every custom element to make a production ready 1.0 release as soon as possible. Pull requests and feedback is highly welcome and should be made via the Github project page.

Features

MQTT 3.1ok
MQTT 3.1.1ok
LWTok
SSL/TLSok
Automatic Reconnectok
QoS 0ok
QoS 1ok
QoS 2ok
Authenticationok
ThrottlingLimited

Usage

Installation

You need node.js and bower installed to use the <mqtt-elements>.

To install bower use:

To install and save <mqtt-elements>:

This will create a folder in the current directory named bower_components in which all dependencies of <mqtt-elements> and <mqtt-elements> itself are saved in. Now create a HTML file e.g. “index.html” and paste the following markup into the file.

This will load WebComponents.js a polyfill shim for Custom Elements, HTML Imports and Shadow DOM, for browsers that don’t support these specs yet.

Connect

A custom HTML-Element is most likely declared in HTML and not created via code. To create a MQTT-Connection instance a connection is declared in HTML with:

within the <body> Tag of the HTML file. The following example will create a MQTT-Connection as soon as possible and automatically connect to iot.eclipse on port »80« and use WebSockets as a transport layer.

To check if the connection is established use a private MQTT-Broker and verify in the log messages or paste the following command into the console in your browser:

The output should be true if a connection to the MQTT broker could be established.

Connect with MQTT 3.1 or MQTT 3.1.1

<mqtt-elements> connect with MQTT 3.1.1 by default. To connect with MQTT 3.1 supply the following parameter via the mqtt-connection#options object.

Please note the single and double quoting of the options property of the mqtt-connection element is needed so that Polymer is able to parse the String into a JSON-Object.

Connect with LWT

The example above will create a connection to iot.eclipse.org and set the Will RETAIN, Will QoS and Will flag in the CONNECT packet that is send to the MQTT broker. To test if the LWT is set properly use a different MQTT client and subscribe to the LWT topic, in this example we used “dead”. If you refresh the browser with the <mqtt-elements> element and the LWT, you should see the message “myplayload” on the topic “dead”.

Connect with Username / Password

Like the LWT, username and password for a MQTT connection is supplied via the option property and send with the MQTT CONNECT packet to the MQTT broker.

Publish

Will publish the message »this is easy« on the topic »foo/bar« as soon as the mqtt-connection element establishes a connection to the »iot.eclipse« MQTT broker. While writing this post I tested my code and found a minor bug that is now documented at Github. This actually prevents the message from being send directly after the connection is established. Either alter the payload via mqtt-publish#payload

to automatically publish to »foo/bar« or

call mqtt-publish#publish manually. With the publication of this blogpost I believe the issue to be fixed.

To publish on multiple topics, any number of mqtt-publish elements can be added to the mqtt-connection element for e.g. see the example below to publish on the three topics »foo/bar«, »client/status« and »client/location«.

Changing the <mqtt-publish>#qos property to 1 or 2 will send the MQTT PUBLISH message with QoS level one or two.

Publish a retained message

To publish a retained MQTT message just add the » retained« flag to the mqtt-publish element and the message should be retained at the broker.

Any client that will subscribe to the topic »foo/bar« should then receive the last retained message to the topic.

Subscribe

This will add a subscription to the topic »foo/bar«. The last message to the topic will be saved in the mqtt-subscription#lastMessage property. To actually use of the message we can use the data binding feature provided by Polymer like this:

To use Polymers data binding feature outside of a custom element, Polymer provides a custom element called »dom-bind« that extends the HTML »template« element. That allows the binding of properties to variables. Every time a new message is published on »foo/bar« the object in mqtt-subscription#lastMessage will be updated and the update will be reflected to the »{{message}}« variable. By default the payload of the MQTT message is expected to be a Unicode String and parsed with String.fromCharCode . The raw Uint8Array payload can be accessed via {{message.message.payload}} or overwrite the mqtt-subscription#payloadParseFunction with a function to parse the raw payload. The parsed payload will be stored in the mqtt-subscription#lastMessage.parsedPayload property. This allows the implementation to be easily extended to work with custom binary messages send via MQTT.

In addition by default each mqtt-subscription stores the last mqtt-message within the mqtt-subscription#messages array. To store the last n messages set the mqtt-subscription#numberOfMessages to n e.g. n=10 to store the last 10 messages.

The following example will store every/infinite message(s) received by the mqtt-subscription in the mqtt-subscription#messages array.

Unsubscribe

To unsubscribe from a subscription just remove the mqtt-subscription element from the DOM and the mqtt-connection will automatically unsubscribe the topic at the MQTT broker.

Disconnect

To disconnect either call mqtt-connection#disconnect manually or just remove the element from the DOM.

or

Full example application

As a proof of concept – a fully working MQTT-client, build with <mqtt-elements>, is available at http://mqttjs.github.io/mqtt-elements/. The client allows the user to create one connection, subscribe to multiple topics and publish to those topics. The code is available in the <mqtt-elements> Github repository and is not even 300 lines of code/markup and some CSS. The following examples highlight some parts of the client to explain the usage of <mqtt-elements>.

At first – one mqtt-connection element is declared to create the connection. Within the element a »dom-repeat« template element is used to iterate over all items in the »{{topics}}« array. For each item in the array one mqtt-subscription element is created, that subscribes to the topic of the item. Now to add one subscription it is only necessary to push an additional topic item to the topics array. Luckily the implementation of »dom-repeat« is smart enough to create DOM elements only once and not every time the array is altered. This makes it possible to just remove the topic item from the »topics« array to remove and unsubscribe one mqtt-subscription.

The mqtt-connection element exposes the property »subscriptions« via that a reference to every mqtt-subscription can be accessed. This array can be used to iterate over every subscription to render every MQTT message received by each MQTT subscription.
The following example iterates over every subscription stored in mqtt-connection#subscriptions and prints out the topic and the QoS. Within a second loop every message of that subscription rendered out, printing the topic, QoS and the parsed payload of the message.

One feature of <mqtt-elements> is that the MQTT.js client that is created to establish the MQTT connection, can be shared/ injected across multiple element instances. The following example demonstrated the injection of the client of the first mqtt-connection element into the second and third mqtt-connection element. Sharing the same WebSocket connection between elements saves resources and keeps the application maintainable.

Feedback and suggestions regarding <mqtt-elements> are highly welcome, pleas submit your experiences via email or Github.

Author Information

sandro_kock
Sandro Kock
Since 2014 Sandro Kock is a mobile developer at SSV Software Systems, responsible for developing mobile solutions, with a focus on IoT/M2M. Before that he wrote the MQTT client MQTTlens, which is based on Polymer.
  Website

Leave a Reply

Your email address will not be published. Required fields are marked *