Skip to content

mqtt-elements - MQTT Client Library Encyclopedia

by Sandro Kock
(updated on ) 16 min read

<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.

Overview of mqtt-elements

Language Javascript
License MIT
Website https://github.com/mqttjs/mqtt-elements
API Style declarative

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 are highly welcome and should be made via the GitHub project page.

Features Supported by mqtt-elements

MQTT 3.1 Yes
MQTT 3.1.1 Yes
LWT Yes
SSL/TLS Yes
Automatic Reconnect Yes

Advance Features Supported by mqtt-elements

Feature
QoS 0 Yes
QoS 1 Yes
QoS 2 Yes
Authentication Yes
Throttling limited

Usage

Installation of mqtt-elements

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

To install the bower, use:

$ npm install –g bower 

To install and save <mqtt-elements>:

$ bower install –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.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>mqtt-elements</title>
  <script type="text/javascript" src="bower_components/webcomponentsjs/webcomponents-lite.js"></script>
  <link rel="import" href="bower_components/mqtt-elements/mqtt-elements.html">
</head>
<body unresolved class="fullbleed">

</body>
</html>

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.

How to Connect mqtt-elements to an MQTT Broker?

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:

<mqtt-connection url="ws://HOST:PORT"></mqtt-connection>

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.

<mqtt-connection url="ws://iot.eclipse.org:80/ws" auto></mqtt-connection>

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:

document.querySelector("mqtt-connection").connected

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.

<mqtt-connection
    url="ws://iot.eclipse.org:80/ws" 
    options='{"protocolId": "MQIsdp", "protocolVersion": 3}' 
    auto>
</mqtt-connection>
    

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

<mqtt-connection
    url="ws://iot.eclipse.org:80/ws"
    options='{"will": {"topic": "dead", "payload": "mypayload", "qos": 1,"retain": true}}' 
    auto>
</mqtt-connection>

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

<mqtt-connection
    url="ws://iot.eclipse.org:80/ws"
    options='{"username": "USERNAME", "password": "PASSWORD"}'
    auto>
</mqtt-connection>

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.

How to Publish MQTT Messages Using mqtt-elements?

<mqtt-connection
    url="ws://iot.eclipse.org:80/ws"
    auto>
  <mqtt-publish topic="foo/bar" payload="this is easy" auto></mqtt-publish>
</mqtt-connection>

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 sent directly after the connection is established. Either alter the payload via mqtt-publish#payload

document.querySelector("mqtt-publish").payload="Not so easy"

to automatically publish to foo/bar or

document.querySelector("mqtt-publish").publish()

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.

<mqtt-connection
    url="ws://iot.eclipse.org:80/ws"
    auto>
  <mqtt-publish topic="foo/bar" payload="this is easy" auto></mqtt-publish>
  <mqtt-publish topic="client/status" payload="online" auto></mqtt-publish>
  <mqtt-publish topic="client/location" payload="{'foo': 'bar'}" auto></mqtt-publish>
</mqtt-connection>

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

<mqtt-connection
url="ws://iot.eclipse.org:80/ws"
auto>
<mqtt-publish topic="foo/bar" payload="this is easy" qos="1" auto></mqtt-publish>
</mqtt-connection>

How to Publish a Retained Message Using mqtt-elements?

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.

<mqtt-connection
    url="ws://iot.eclipse.org:80/ws"
    auto>
  <mqtt-publish topic="foo/bar" payload="this is easy" retained auto></mqtt-publish>
</mqtt-connection>

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

How to Subscribe to an MQTT Message Using mqtt-elements?

<mqtt-connection
    url="ws://iot.eclipse.org:80/ws"
    auto>
  <mqtt-subscription topic="foo/bar"></mqtt-subscription>
</mqtt-connection>

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:

<template is="dom-bind">
  <mqtt-connection
      url="ws://iot.eclipse.org:80/ws"
      auto>
    <mqtt-publish topic="foo/bar" payload="lost"></mqtt-publish>
    <mqtt-subscription topic="foo/bar" last-message="{{message}}"></mqtt-subscription>
  </mqtt-connection>

  <div>{{message.topic}}</div>
  <div>{{message.message.dup}}</div>
  <div>{{message.message.retain}}</div>
  <div>{{message.message.qos}}</div>
  <div>{{message.parsedPayload}}</div>
</template>

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 sent 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. For example, 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.

<mqtt-connection
    url="ws://iot.eclipse.org:80/ws"
    auto>
<mqtt-subscription topic="foo/bar" number-of-messages="Infinity"></mqtt-subscription>
</mqtt-connection>

How to Unsubscribe an MQTT Message Using mqtt-elements?

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.

document.querySelector("mqtt-subscription").remove()

How to Disconnect?

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

document.querySelector("mqtt-connection").disconnect()

or

document.querySelector("mqtt-connection").remove()

Full Example Application of mqtt-elements

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>.

<!--create mqtt-connection element-->
<mqtt-connection
        id="connection"
        url="[[url]]"
        connected="{{connected}}"
        client="{{client}}"
        subscriptions="{{subscriptions}}"
        options='{{options}}'
        on-mqtt-message="_handelMqttMessage">

<!--create a mqtt subscription for every item in topics-->
<template is="dom-repeat" items="{{topics}}" as="t">
<mqtt-subscription topic="[[t.topic]]"
                           number-of-messages="10"
                           qos="[[t.qos]]"></mqtt-subscription>
</template>

<!--create mqtt-publish element to publish mqtt messages to the broker -->
<mqtt-publish id="pub"
                    topic="[[topic]]"
                    payload="[[value]]"
                    auto$="[[pubAuto]]"
                    qos="[[pubQos]]"
                    retained="[[pubRetained]]"></mqtt-publish>
</mqtt-connection>

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.

<!--output every subscription-->
<template is="dom-repeat" items="[[subscriptions]]" as="sub" observe="messages.*">
  <span>[[sub.topic]]</span>
  <span>[[sub.qos]]</span>
  <template is="dom-repeat" items="{{sub.messages}}" as="message">
    <div>{{message.topic}}</div>
    <div>{{message.message.qos}}</div>
    <div>{{message.parsedPayload}}</div>
  </template>
</template>

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.

<mqtt-connection
    auto
    url="ws://iot.eclipse.org:80/ws"
    client="{{client}}">
</mqtt-connection>

<mqtt-connection
    client="[[client]]">
  <mqtt-subscription topic="foo/bar"></mqtt-subscription>
</mqtt-connection>

<mqtt-connection
    client="[[client]]">
  <mqtt-subscription topic="other/topic"></mqtt-subscription>
</mqtt-connection>

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

Sandro Kock

Sandro Kock is a mobile developer at SSV Software Systems, responsible for developing mobile solutions, with a focus on IoT/M2M. The maintainer of mqtt-elements, a set of MQTT WebComponents, created with Polymer.

  • Sandro Kock on GitHub
  • Contact Sandro Kock via e-mail

Related content:

HiveMQ logo
Review HiveMQ on G2