MQTT Client Library Encyclopedia – MQTT.js

Guest post by Matteo Collina

MQTT.js
Language Javascript
Website https://github.com/mqttjs/MQTT.js
API-Style Asynchronous, Callbacks, Streams, Offline
License MIT

Description

The MQTT.js provides a full-featured Javascript library for the MQTT protocol. It is fully isomorphic, which means it can run in the browser and in node.js (>= 0.8), including Intel Edison and Raspberry PIs. In fact, it is bundled in base image of the Intel Edison.
The library was originally written by Adam Rudd in May 2011, and it has been upgraded to all versions of node.js since then. In 2014, Matteo Collina took over as a maintainer, and since version 1.0.0 it supports MQTT over Websockets, both in Node.js and in the Browser.
This library is production ready and used by some fortune 500 companies. It can support long running clients with spotty connectivity. It has an optional on-disk storage for local offline messaging.
MQTT.js became Open Open Source last January, and it had 55 contributors in its history. There is a team of 4 that maintains the library.

Features

MQTT 3.1 ok
MQTT 3.1.1 ok
LWT ok
SSL/TLS ok
Automatic Reconnect ok
QoS 0 ok
QoS 1 ok
QoS 2 ok
Authentication ok
Throttling Limited

Usage

Installation

You need node.js installed to use MQTT.js, then:

npm install mqtt

If you want to use the embedded CLI tools, you need to

npm install mqtt -g

Connect

mqtt.connect([url], options)

Connects to the broker specified by the given url and options and returns a Client.

The URL can be on the following protocols: `’mqtt’, ‘mqtts’, ‘tcp’, ‘tls’, ‘ws’, ‘wss’`. The URL can also be an object as returned by `URL.parse()`, in that case the two objects are merged, i.e. you can pass a single object with both the URL and the connect options.

You can also specify a servers options with content: `[{ host: ‘localhost’, port: 1883 }, … ]`, in that case that array is iterated at every connect.

var mqtt    = require('mqtt');
var client  = mqtt.connect('mqtt://broker.mqttdashboard.com');

Connect with MQTT 3.1 or MQTT 3.1.1

The library connects with MQTT 3.1.1 by default. To connect with MQTT 3.1

var mqtt    = require('mqtt');
var client  = mqtt.connect(‘mqtt://broker.mqttdashboard.com',{
  protocolId: 'MQIsdp',
  protocolVersion: 3
});

Connect with LWT

LWT can be set in the connect function, like the following:

var mqtt    = require('mqtt');
var client  = mqtt.connect(‘mqtt://broker.mqttdashboard.com',{
  will: {
    topic: ‘dead’,
    payload; ‘mypayload’,
    qos: 1,
    retain: true
  }
});

Connect with Username / Password

Username and password can be set in the connect function, like the following:

var mqtt    = require('mqtt');
var client  = mqtt.connect(‘mqtt://broker.mqttdashboard.com',{
  username: ‘myuser’,
  password: ‘mypassword’
});

Publish

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

Publish a message to a topic

  • `topic` is the topic to publish to, `String`
  • `message` is the message to publish, `Buffer` or `String`
  • `options` are the options to publish with, including:
    • `qos` QoS level, `Number`, default `0`
    • `retain` retain flag, `Boolean`, default `false`
  • `callback` callback fired when the QoS handling completes, or at the next tick if QoS 0.

Subscribe

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

Subscribe to a topic or topics

  • `topic` is a `String topic` to subscribe to or an `Array of topics` to subscribe to. It can also be an `object`, the object `key` is the `topic name` and the `value` is the `QoS`, like `{‘test1’: 0, ‘test2’: 1}`.
  • `options` is the options to subscribe with, including:
    • `qos` qos subscription level, `default 0`
  • `callback` – `function(err, granted)` callback fired on suback where:
    • `err` is a `subscription error`
    • `granted` is an `array of {topic, qos}` where:
      • `topic` is a `subscribed to topic`
      • `qos` is the `granted qos level` on it
client.subscribe(‘presence');

client.on('message', function (topic, message) {
  // message is Buffer
  console.log(message.toString());
  client.end();
});

Unsubscribe

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

Unsubscribe from a topic or topics

`topic` is a `String topic` or an `array of topics` to unsubscribe from
`callback` fired on `unsuback`

Disconnect

Using SSL / TLS

The user should call mqtt.connect(), here is a full example:

var mqtt = require('mqtt');
var fs = require('fs');
var KEY = __dirname + '/tls-key.pem';
var CERT = __dirname + '/tls-cert.pem';
var TRUSTED_CA_LIST = [__dirname + '/crt.ca.cg.pem'];

var PORT = 1883;
var HOST = 'stark';

var options = {
  port: PORT,
  host: HOST,
  keyPath: KEY,
  certPath: CERT,
  rejectUnauthorized : true, 
  //The CA list will be used to determine if server is authorized
  ca: TRUSTED_CA_LIST
};

var client = mqtt.connect(options);

client.subscribe('messages');
client.publish('messages', 'Current time is: ' + new Date());
client.on('message', function(topic, message) {
  console.log(message);
});

client.on('connect', function(){
	console.log('Connected');
});

Author Information

mateo
Matteo Collina
Matteo is a code pirate and mad scientist. He spends most of his days programming in node.js, but in the past he worked with Ruby, Java and Objective-C. He recently got a Ph.D. with a thesis titled “Application Platforms for the Internet of Things”. Now he is a Software Architect at nearForm, where he consults for the top brands in world. Matteo is also the author of the Node.js MQTT Broker, Mosca and of the LevelGraph database. Matteo spoke at several international conferences: NodeSummit, Nodeconf.eu, LXJS, Distill by Engine Yard, and JsDay to name a few. He is also co-author of the book “Javascript: Best Practices” edited by FAG, Milan. In the summer he loves sailing the Sirocco.
  Website

14 comments

  1. Saili Ghavat says:

    I am trying to connect to an mqtt broker but I get this error when I try top use require.js
    Uncaught Error: Module name “mqtt” has not been loaded yet for context: _. Use require([])

    1. Mosquitto says:

      Have you imported de mqtt module?: –> var mqtt = require(‘mqtt’);

  2. bedinsky says:

    Hi,
    I’m using MQTT.js 2.2.1 with websocket
    I’ve set
    var mqtt = require(‘mqtt’);
    var client = mqtt.connect(‘ws://broker.mqttdashboard.com’,{
    protocolId: ‘MQIsdp’,
    protocolVersion: 3
    });

    I cannot connect to hiveMQ, client stays in a connection loop
    client is working with mqtt://

    please tell me how I can connect to HiveMQ using websocket
    it seems to me that MQTT.js is setting protocolId to mqttv3.1
    and broker does not recognize such protocol

    regards

    1. Hi there,

      please follow this instruction, to correctly configure your HiveMQ for Websockets.
      Note that there is a known issue for paho.js and websockets.

      Hope that helps.

      Florian, from the HiveMQ Team.

  3. bedinsky says:

    Thank you !
    I successfully connected from an ionic2 app using
    mqtt.connect(‘ws://broker.hivemq.com’, {port: 8000,path: ‘/mqtt’ });

    regards

    1. Frank says:

      Thank you bedinsky, this format worked for me!

  4. Vikas Mujumdar says:

    I am building an AngularJS application to connect to Mosquitto. I use the Paho client successfully to connect to the broker via websockets. No problems there. I wanted a client that could connect to the broker via the basic MQTT (port 1883) since Paho does not support that. I am trying with mqtt.js but it always forces the URL to ws://hostname even though my code has mqtt://hostname. I am running my application on Chrome.

    I am including the library from the CDN:
    I am not adding the “require” statement since it is a client side script
    Code has: var client = mqtt.connect(‘mqtt://iot.eclipse.org:1883/mqtt’);

    Error in console:
    WebSocket connection to ‘ws://iot.eclipse.org:1883/mqtt’ failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET

    What am I doing wrong? Or is my understanding incorrect that I can choose to connect via mqtt or ws?

    1. Hallo Vikas,

      this is actually a browser / security issue. A tcp connection that is not wrapped in websockets can not be opened in JavaScript.

      This is not a restriction of the language itself but of it’s use inside the sandbox within the browser. Just imagine that a script somewhere on the internet gets loaded into the browser and could from inside the browser access every computer reachable by the browser with arbitrary protocols. You could easily misuse this to send spam through a companies internal mail server or attack/misuse other internal and external resources.

      Hope that helps.

      Best regards,
      Florian, from The HiveMQ Team.

  5. R.vignesh says:

    how can I send the disconnect messages to subscriibed clients if one client is disconnected in MQTT?
    Hello All I tried client 1 and client 2 program I can able to easily communicate with them.I can easily send the messages and receive the messages with them.but I don’t know if one client is disconnected, how can I send the disconnected message to subscribed clients.can anyone help me.I need urgently.Thanks in advance.I am waiting for your reply
    client 1:

    var mqtt=require(“mqtt”);
    var express=require(“express”);
    var app=express();
    var options={
    keepalive:100,
    port: 1883,
    clientId:’1′,
    clientSession:false,
    host: “http://localhost:8000″,
    will:
    {
    topic:’willMag’,
    payload:”connection closed abnormallly r”,
    qos:1,
    retain:true
    }
    };
    var client=mqtt.connect(“tcp://192.168.43.137:1883”,options);
    client.on(“connect”,function()
    {
    setInterval(function()
    {
    client.publish(“ranjith/princy”,”hello love you princy”,function()
    {
    console.log(“message published in client1”);
    });
    },2000);
    client.subscribe(“bv/nivi”);
    client.on(“message”,function(topic,message)
    {
    console.log(“I recieved the topic:”+topic);
    console.log(“I recieved the message:”+message);
    });
    });
    client.on(“disconnect”,function()
    {
    console.log(“disconnected client1”);
    });
    app.listen(8000,function()
    {
    console.log(“server listen at port 8000”);
    });

    client 2:
    var mqtt=require(“mqtt”);
    var express=require(“express”);
    var app=express();
    var options={
    keepalive:100,
    port: 1883,
    clientId:’2′,
    clientSession:false,
    host: “http://localhost:8086″,
    will:
    {
    topic:’willMag’,
    payload:”connection closed abnormallly b”,
    qos:1,
    retain:true
    }
    };
    var client=mqtt.connect(“tcp://192.168.43.137:1883”,options);
    client.on(“connect”,function()
    {
    setInterval(function(){
    client.publish(“bv/nivi”,”hello love you nivi”,function()
    {
    console.log(“message published in client2”);
    });
    },2000);

    client.subscribe(“ranjith/princy”);

    client.on(“message”,function(topic,message)
    {
    console.log(“I recieved the topic:”+topic);
    console.log(“I recieved the message:”+message);
    });

    });
    client.on(“disconnect”,function()
    {
    console.log(“disconnected client2”);
    });
    app.listen(8086,function()
    {
    console.log(“server listen at port 8000”);
    });

  6. Raju says:

    Can you please let me know how to use the sample code given above for Secure connection. I have the CA and tried the above code but borker returns error { Error: certificate has expired
    at Error (native)
    at TLSSocket. (_tls_wrap.js:1055:38)
    at emitNone (events.js:86:13)
    at TLSSocket.emit (events.js:185:7)
    at TLSSocket._finishInit (_tls_wrap.js:580:8)
    at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:412:38) code: ‘CERT_HAS_EXPIRED’ }

    This happens even just with rejectUnauthorized : true, in options.
    Please help me resolve this issue

    1. Hi Raju,

      it looks like you are using an expired certificate and your client is rejecting it.
      This error code is not sent by the broker.

      Kind regards,
      Florian from the HiveMQ Team.

  7. Raju says:

    Thank you. I am using a valid certificate and the expiry date is 2026. My other application/client are able to connect to the broker using same ca certificate.
    I am using the root ca and which is .crt format. Can this create any issue, do I need to convert .crt to .pem
    Regards
    -raju

    1. Raju says:

      I am getting this error even for a wrong file the moment I set rejectUnauthorized=true.
      I am using “mqtt”: “2.8.0” node package. Please let me know would there be any issues.

    2. Hi Raju,

      this appears to be an issue within the MQTT.JS implementation.
      For question regarding MQTT.JS please refer to the MQTT.JS webpage
      Just to make sure, this is not caused by a faulty HiveMQ configuration, you can check the HiveMQ User Guide Appendix
      It explain in detail how to configure TLS/SSL on both server and client side for HiveMQ. Should you run into any problem with the HiveMQ configuration, you can contact our support team (support@hivemq.com)
      I hope this helps.

      Kind regards,
      Florian from The HiveMQ Team.

Leave a Reply

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