MQTT client for Node.js
Tutorial to use the Node.js MQTT client with FairCom's MQTT broker engine
This section contains MQTT Client tutorials for Node.js developers.
This section contains MQTT Client tutorials for Node.js developers.
Introduction
This quick start guide includes two tutorials. Both are command-line programs that you can use to publish messages and monitor published messages. Thus, the tutorials perform double duty. They show you how to use MQTT and they create command-line utilities that you can use to learn and troubleshoot MQTT.
The first is a program that publishes MQTT messages to the broker.
The second is a program that subscribes to messages.
FairCom MQ is an MQTT broker. Programs use an MQTT client library to publish and subscribe to messages on the MQTT broker.
Connects to an MQTT broker.
Publishes a message to a topic.
Subscribes to a topic and receives all messages published to that topic by any client.
Installation
FairCom MQ (or another MQTT broker) must be running on 127.0.0.1 and listening on port 1883.
The latest stable version of Node.js must be installed.
In the directory, <faircom>/drivers/nodejs.mqtt/NodejsMQTTTutorial1, run
npm install
to load the requirednode_modules
.Note
It is important that your computer be connected to the internet when you run
npm install
because around 80 modules will be downloaded and installed.
Code dependencies
The tutorial uses the MQTT.js Client Library for Node.js to communicate with MQTT. The MQTT.js client library is an open-source project using the MIT license.
Note
FairCom chose the MQTT.js client library over the Paho MQTT library because it works well, supports all versions of MQTT, uses an MIT license and is an active, mature project on GitHub.
This tutorial is a command-line utility for publishing MQTT messages. It publishes a message to a specified topic on a specified broker. This is useful for testing and troubleshooting MQTT.
The source code is simple and self-explanatory and is located in the <faircom>/drivers/nodejs.mqtt/NodejsMQTTTutorial1/publish/publish.js
file.
Command line usage
node publish.js -t topic -f fileName -q qos -c clientid -s hostname:port -u username -p password
Command line options
Options may be present in any order, and if absent, default values will be used.
Option | Description |
---|---|
| An optional topic to publish to. It defaults to |
| A required file name to use for the payload in the published message. The file may contain anything. |
| An optional quality of service to use when publishing the message. It defaults to
|
| An optional client id that uniquely identifies the client to the MQTT broker. It defaults to |
| An optional hostname and port of an MQTT broker. It defaults to |
| An optional user name to use when connecting to the broker. If absent, a connection without a username and password is attempted. |
| An optional password to use with the username provided above. If absent a username without a password is attempted. |
| Prints the usage and exit. |
node publish.js -t testTopic -f /Users/username/myjsonfiles/data.json
connecting to client at: mqtt://127.0.0.1:1883 connected to client at: mqtt://127.0.0.1:1883 publishing to topic testTopic Connection closed by client
Code
// Variable declarations and initialization const argv = require('yargs').argv, mqtt = require('mqtt'), process = require('process'), validation = require('./validation') const fs = require('fs') let client = null, hasHelpParam = validation.hasHelpParam(argv), hasRequiredParams = validation.hasRequiredParams(argv) // Default settings used to configure MQTT client var settings = { brokerAddress: '127.0.0.1:1883', clientID : 'testPubClientID', fileName : null, qos : 1, topic : 'testTopic', username : null, password : null } if (hasHelpParam) { validation.usage() } /* Parameter exit conditions 1 - User passed the 'help' parameter 2 - User didn't pass required parameters 3 - User pressed Ctrl + C */ if (hasHelpParam || !hasRequiredParams) { process.exit() } process.on('SIGINT', function () { console.log('\nshutting down MQTT client after Ctrl C') process.exit() }) // Override default 'settings' object properties using params passed by user. Object.keys(argv).forEach((key) => { let property = validation.getArgProperty(key) if (property != null) { settings[property] = argv[key] } }) // Connect to client connection. console.log(`connecting to client at: ${settings.brokerAddress}`) client = mqtt.connect(`mqtt://${settings.brokerAddress}`, { clientId : settings.clientID, connectTimeout : 30 * 1000, reconnectPeriod: 1000, protocolId : 'MQIsdp', protocolVersion: 3, ...((settings.username !== null) && { username: settings.username }), ...((settings.password !== null) && { password: settings.password }) }) // Add mqtt client event listeners client.on('connect', function () { console.log(`connected to broker at: ${settings.brokerAddress}`) // read in file from fileName path passed in by user. console.log(`reading file at ${settings.fileName}`) try { const fs = require('fs'), msgData = fs.readFileSync(settings.fileName); publishMsg(msgData) } catch (e) { if (e.code !== 'MODULE_NOT_FOUND') { client.end() throw e } } }, ) client.on('error', function (err) { console.log('Error: ' + err) if (err.code === 'ENOTFOUND') { console.log( 'Network error: Verify the passed hostname:port and that ' + 'your MQTT server is running.') } }) client.on('close', function () { console.log('connection closed by client') if (client.isConnected) { client.end() } process.exit() }) function publishMsg (msgData) { console.log(`publishing to topic ${settings.topic}`) client.publish(settings.topic, JSON.stringify(msgData), { qos: settings.qos }) client.end() }
This tutorial is a utility for subscribing to MQTT messages in a topic. Each message sent to the topic is output to the console and optionally written as a file to the specified folder. This utility is useful for testing and troubleshooting MQTT.
The source code is simple and self-explanatory and is located in the <faircom>/drivers/nodejs.mqtt/NodejsMQTTTutorial1/subscribe/subscribe.js
file.
Command line usage
node subscribe.js -t topic -d directory -q QoS -c clientID -s hostname:port -u username -p password
Command line options
Options may be present in any order, and if absent, default values will be used.
Option | Description |
---|---|
| An optional topic to subscribe to. It defaults to |
| An optional directory to save messages as files. If omitted, messages will be printed to screen and not saved to files. If you specify a directory that does not exist, it is created. Existing files in the directory with the same name are overwritten. |
| An optional quality of service to use when when subscribing to the topic. It defaults to
|
| An optional client id that uniquely identifies the client to the MQTT broker. It defaults to |
| An optional hostname and port of an MQTT broker. It defaults to |
| An optional user name to use when connecting to the broker. If absent, a connection without a username and password is attempted. |
| An optional password to use with the username provided above. Ignored if the username is absent. |
| Prints the usage and exit. |
node subscribe.js -t testTopic -d testDir -c testSubClientID
connecting to broker at: 127.0.0.1:1883 connected to broker at: 127.0.0.1:1883 subscribing to topic: testTopic Messages that arrive will be printed to the screen. received message: { "property": "value", "string": "string", "number": 1, "boolean": true, "null...
Store incoming message
When a directory is specified, the utility writes the payload of each received message to a file. The name of the file is the name of the topic you specified followed by an underscore plus a sequential number. Topic names are case-sensitive. The file has no extension because an MQTT payload can be anything.
testTopic_000001
testTopic_000002
testTopic_000003
testTopic_000004
Code
module.exports = { getArgProperty: function (arg) { let property = null switch (arg.toLowerCase()) { case 's': case 'server': case 'broker': case 'brokeraddress': property = 'brokerAddress' break case 't': case 'topic': property = 'topic' break case 'c': case 'client': case 'clientid': property = 'clientID' break case 'f': case 'file': case 'filename': property = 'fileName' break case 'u': case 'user': case 'username': property = 'username' break case 'p': case 'pass': case 'password': property = 'password' break case 'q': case 'qos': property = 'qos' break } return property }, hasHelpParam: function(argv) { return Object.keys(argv).some(k => (k === 'h')) || Object.keys(argv).some(k => k.startsWith('help') ); }, hasRequiredParams: function(argv) { let hasFileNameProperty = Object.keys(argv).some(k => (k === 'f')) || Object.keys(argv).some(k => k.startsWith('file') ) if (!hasFileNameProperty && !this.hasHelpParam(argv)) { console.log(`The fileName (-f) parameter is required.`) return false; } return true; }, usage: function () { console.log(` Usage: node publish.js -f /pathtofile/sample.json Publish the contents of a file to a broker using the specified topic. Options: -s server Server address. Defaults to \"127.0.0.1:1883\" -t topic The topic to publish to. Defaults to \"testTopic\". -c clientID The unique ID to use when connecting to the broker. Defaults to \"testPubClientID\". -f fileName The file to use as a payload to publish. -u username An optional username to authenticate with when connecting to the broker. If absent, a connection without credentials will be attempted. -p password The password to use with the username provided above. Ignored if the username is absent. -q qos The Quality Of Service to publish with. Defaults to 1. -h help Print the usage and exit. Options may be present in any order, and if absent, default values will be used. Invalid options will be ignored. `) }, }
Don't hesitate to contact us with questions, suggestions, and bug reports. We want you to be successful.
Address:
6300 W. Sugar Creek Drive
Columbia, Missouri 65203-9052
Phone:
800.234.8180