React is an open-source front-end JavaScript library for creating user interfaces or UI components. It is sometimes known as React.js or ReactJS. Facebook and a group of independent programmers and businesses collectively maintain it. Mobile or single-page applications can be built using React as a framework. React, however, primarily focuses on rendering data to the DOM. Therefore, to create React apps, extra frameworks for state management and routing are typically needed. Examples of these libraries include Redux and React Router, respectively. This post primarily explains how to build connect, subscribe, messaging, and unsubscribe between the client and MQTT broker using the React project.
Pre-requisites – Websockets
For this tutorial, ensure you have activated web sockets to connect to the broker using a web client.
WebSocket is one of the communication protocols which provides full duplex communication over a single TCP/IP connection. It uses HTTP as an initial connection establishment. The WebSocket enables communication from the web browser (client) to the server, in which you can send some data or real-time data to the client from the server or even bidirectional. At first, the client and the server interact with HTTP, then the connection upgrades to the WebSocket, providing full duplex communication, unlike HTTP.
HTTP Protocol always uses long polling, but Websockets overcomes this problem. Because the HTTP protocol always sends the data on request/response, and the WebSockets allows the server to send the data to the web browser or the client, even without any request from the browser. So, 2-way client-server communication is possible with WebSockets.
Follow this tutorial to activate the WebSockets on your Windows or Linux machine.
Step 1 Create a new react project.
Create a new react application, “mqtt-dashboard“
npx create-react-app mqtt-dashboard
Step 2 Install the MQTT.js client on your project.
MQTT.js is a client library for the MQTT protocol, written in JavaScript for node.js and the browser.
cd mqtt-dashboard
npm install mqtt
Step 3 Edit your src/App.js file
Provide all the information related to the Broker in the file. We will only subscribe to the broker from our client.
import React, { useState, Fragment } from "react";
import "./App.css";
var mqtt = require("mqtt");
var options = {
protocol: "ws",
username: "xxxxxxxxx",
password: "xxxxxxxx",
keepalive: 20,
// clientId uniquely identifies client
// choose any string you wish
clientId: "mqttjs_" + Math.random().toString(16).substr(2, 8),
};
var client = mqtt.connect("mqtt://<your IP address>:<your websocket port>", options);
client.subscribe("publishtopic");
console.log("Client subscribed ");
function App() {
var note;
client.on("message", function (topic, message) {
note = message.toString();
// Updates React state with message
setMsg(note);
console.log(note);
client.end();
});
// Sets default React state
const [msg, setMsg] = useState(
<Fragment>
<em>...</em>
</Fragment>
);
return (
<div className="App">
<header className="App-header">
<h1>Hello MQTT in React</h1>
<p>The message payload is: {msg}</p>
</header>
</div>
);
}
export default App;
Step 4 Change the Settings for Webpack 5
Run the React project from your terminal.
npm start
When you start the app, if you are getting following error,
constants.js:46 Uncaught ReferenceError: Buffer is not defined
at Object../node_modules/mqtt/node_modules/mqtt-packet/constants.js (constants.js:46:1)
at Object.options.factory (react refresh:6:1)
at __webpack_require__ (bootstrap:24:1)
at fn (hot module replacement:61:1)
at Object../node_modules/mqtt/node_modules/mqtt-packet/parser.js (parser.js:4:1)
at Object.options.factory (react refresh:6:1)
at __webpack_require__ (bootstrap:24:1)
at fn (hot module replacement:61:1)
at Object../node_modules/mqtt/node_modules/mqtt-packet/mqtt.js (mqtt.js:1:1)
The error states that the buffer is not defined. You can view this error in the console of your browser.
Follow the steps below to overcome this error.
- inside of node_modules/mqtt create webpack.config.js:
const webpack = require('webpack')
module.exports = {
entry: "./lib/connect/index.js",
//mode: "development",
output: {
library: {
type: "commonjs2"
},
filename: "mqtt.browser.js"
},
plugins: [
// fix "process is not defined" error:
// (do "npm install process" before running the build)
new webpack.ProvidePlugin({
process: 'process/browser',
}),
new webpack.ProvidePlugin({
Buffer: [ 'buffer', 'Buffer' ],
}),
],
resolve: {
fallback: {
assert: require.resolve('assert'),
buffer: require.resolve('buffer'),
console: require.resolve('console-browserify'),
constants: require.resolve('constants-browserify'),
crypto: require.resolve('crypto-browserify'),
domain: require.resolve('domain-browser'),
events: require.resolve('events'),
http: require.resolve('stream-http'),
https: require.resolve('https-browserify'),
os: require.resolve('os-browserify/browser'),
path: require.resolve('path-browserify'),
punycode: require.resolve('punycode'),
process: require.resolve('process/browser'),
querystring: require.resolve('querystring-es3'),
stream: require.resolve('stream-browserify'),
string_decoder: require.resolve('string_decoder'),
sys: require.resolve('util'),
timers: require.resolve('timers-browserify'),
tty: require.resolve('tty-browserify'),
url: require.resolve('url'),
util: require.resolve('util'),
vm: require.resolve('vm-browserify'),
zlib: require.resolve('browserify-zlib'),
}
}
}
- inside of
node_modules/mqtt/package.json
- add
"type": "commonjs"
(not sure if this is necessary) - under
"browser"
change./mqtt.js": "./lib/connect/index.js"
to"./mqtt.js": "./dist/mqtt.browser.js"
{
...
"type": "commonjs",
"browser": {
"./mqtt.js": "./dist/mqtt.browser.js"
...
}
...
}
- inside of
node_modules/mqtt
execute
npm i
npm i buffer process
npm i webpack webpack-cli
npx webpack
- clean npm cache
delete node_modules/.cache folder
- Rebuild you app
npm start
Credits: https://github.com/mqttjs/MQTT.js/issues/1412
Step 5 Publish MQTT Messages from the MQTTBox
MQTTBox is a cross-platform application that makes it easy to create MQTT clients, virtual device networks, and load test MQTT devices and brokers. It lets you publish messages to an MQTT broker, subscribe to MQTT topics, receive messages, and do load testing. In this tutorial, we will use MQTTBox as an MQTT client and connect to our Mosquitto broker which is already running on a Raspberry Pi.
First, you have to create your MQTT client via the MQTTBox. Enter the host address ( in this case, it’s the IP address of my Pi), your username, and password. The client name can be any string of your own choice.
Next, enter the topic name where you would like to publish and the payload. Click Publish.
In your App.js from your react project, you have already set the username, password and the Host address. Also, you have subscribed from the same topic from where you have published using MQTTBox.
Step 6 Start your React Project
Run the following command from the terminal.
PS C:\Users\Monisha Vasumacharla\Desktop\mqtt-dashboard> npm start
Step 7 Final Output
Click on that link http://localhost:3001 which opens in the browser.
Happy Learning!