# Connect to the Deployment with Electron
This article mainly introduces how to use MQTT (opens new window) in Electron projects, and complete a simple MQTT desktop client, and implement the connection, subscription, unsubscribe, messaging and other functions between the client and MQTT broker (opens new window).
Electron (opens new window) is an open-source software framework developed and maintained by GitHub. It allows for the development of desktop GUI applications using web technologies: it combines the Chromium rendering engine and the Node.js runtime. Electron is the main GUI framework behind several notable open-source projects including Atom, GitHub Desktop, Light Table, Visual Studio Code, and WordPress Desktop.^1 (opens new window)
A basic Electron includes three files: package.json
(metadata) main.js
(code) and index.html
(graphical user interface). The frame is provided by the Electron executable file (electron.exe on Windows, electron.app on macOS, electron on Linux). Developers are free to add flags, customize icons, rename or edit Electron executable files.
# Preconditions
- The deployment has been created. You can view connection-related information under Deployment Overview. Please make sure that the deployment status is running. At the same time, you can use WebSocket to test the connection to the MQTT server.
- Set the user name and password in
Authentication & ACL
>Authentication
for connection verification.
# New project
There are many ways to build a new project, but here is a brief list of a few:
To create manually, do the following in the self-built project directory
cd your-project npm init npm i -D electron@latest
1
2
3
4
5Also, refer to the following documentation for the steps to build the project.
Address: https://www.electronjs.org/docs/tutorial/first-app (opens new window)
Rapid development with the official template projects
electron-quick-start
.Address: https://github.com/electron/electron-quick-start (opens new window)
# Clone this repository git clone https://github.com/electron/electron-quick-start # Go into the repository cd electron-quick-start # Install dependencies npm install # Run the app npm start
1
2
3
4
5
6
7
8Rapid development builds with the template project
electron-react-bolierplate
, which can be developed usingReact.js
.Address: https://github.com/electron-react-boilerplate/electron-react-boilerplate (opens new window)
git clone --depth 1 --single-branch https://github.com/electron-react-boilerplate/electron-react-boilerplate.git your-project-name cd your-project-name yarn
1
2
3The rapid development build of the project via
electron-vue
will be coupled with project initialization using thevue-cli
tool, which can be developed usingVue.js
.Address: https://github.com/SimulatedGREG/electron-vue (opens new window)
# Install vue-cli and scaffold boilerplate npm install -g vue-cli vue init simulatedgreg/electron-vue my-project # Install dependencies and run your app cd my-project yarn # or npm install yarn run dev # or npm run dev
1
2
3
4
5
6
7
8
In this article, the official electron quick start project template will be used to initialize the project in order to quickly build the example project.
# Installation dependencies
Installation through the command line
npm install mqtt --save
After the dependencies are installed, if you want to open the console for debugging, you need to modify the code in main.js
and uncomment win.webContents.openDevTools()
.
// Open the DevTools.
mainWindow.webContents.openDevTools();
2
In this case, the locally installed MQTT.js
module cannot be loaded directly into renderer.js
without using the front-end builder to package the front-end page. In addition to using the build tool method, there are two other ways to solve this:
nodeIntegration
can be set to true inwebPreferences
. When this property is present,webview
will have Node integration in it, and node APIs likerequire
andprocess
can be used to access low-level system resources. Node integration is disabled by default.const mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, preload: path.join(__dirname, "preload.js"), }, });
1
2
3
4
5
6
7
8The MQTT.js module can be imported in preload.js. When there is no node integration, this script still can access all Node APIs. However, when this script execution completes, global objects injected via Node will be removed.
# Connection
Please find the relevant address and port information in the Deployment Overview of the Console. Please note that if it is the basic edition, the port is not 1883 or 8883, please confirm the port.
# Connection settings
This article will use the free public MQTT broker (opens new window) provided by EMQX. This service was created based on the EMQX Cloud (opens new window). The information about broker access is as follows:
- Broker: broker.emqx.io
- TCP Port: 1883
- WebSocket Port: 8083
To illustrate more intuitive, the key connection code for the example will be written in the renderer.js file. With the consideration of security, the installed MQTT module will be loaded via the require method of the Node.js API, in the preload.js file (using method 2 above). Also, this method injecting it in the global window object so that the loaded module can be accessed directly in renderer.js.
- Import MQTT module
// preload.js
const mqtt = require("mqtt");
window.mqtt = mqtt;
2
3
- Configure and test MQTT module
// renderer.js
const clientId = "mqttjs_" + Math.random().toString(16).substr(2, 8);
const host = "mqtt://broker.emqx.io:1883";
const options = {
keepalive: 30,
clientId: clientId,
protocolId: "MQTT",
protocolVersion: 4,
clean: true,
reconnectPeriod: 1000,
connectTimeout: 30 * 1000,
will: {
topic: "WillMsg",
payload: "Connection Closed abnormally..!",
qos: 0,
retain: false,
},
rejectUnauthorized: false,
};
// Information about the mqtt module is available
console.log(mqtt);
console.log("connecting mqtt client");
const client = mqtt.connect(host, options);
client.on("error", (err) => {
console.log("Connection error: ", err);
client.end();
});
client.on("reconnect", () => {
console.log("Reconnecting...");
});
client.on("connect", () => {
console.log("Client connected:" + clientId);
client.subscribe("testtopic/electron", {
qos: 0,
});
client.publish("testtopic/electron", "Electron connection demo...!", {
qos: 0,
retain: false,
});
});
client.on("message", (topic, message, packet) => {
console.log(
"Received Message: " + message.toString() + "\nOn topic: " + topic
);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
We can see the following output on the console after writing the above code and running the project:
The MQTT module works fine. After setting up the module, we can write a simple UI interface to manually enter the configuration required for the MQTT connection, and click the connect button to connect to the MQTT server, as well as disconnect, subscribe to topics, send and receive messages, and so on.
# Interface of application
The complete code is available here: https://github.com/emqx/MQTT-Client-Examples/tree/master/mqtt-client-Electron (opens new window).
# Key code
let client = null;
const options = {
keepalive: 30,
protocolId: "MQTT",
protocolVersion: 4,
clean: true,
reconnectPeriod: 1000,
connectTimeout: 30 * 1000,
will: {
topic: "WillMsg",
payload: "Connection Closed abnormally..!",
qos: 0,
retain: false,
},
};
function onConnect() {
const { host, port, clientId, username, password } = connection;
const connectUrl = `mqtt://${host.value}:${port.value}`;
options.clientId =
clientId.value || `mqttjs_${Math.random().toString(16).substr(2, 8)}`;
options.username = username.value;
options.password = password.value;
console.log("connecting mqtt client");
client = mqtt.connect(connectUrl, options);
client.on("error", (err) => {
console.error("Connection error: ", err);
client.end();
});
client.on("reconnect", () => {
console.log("Reconnecting...");
});
client.on("connect", () => {
console.log("Client connected:" + options.clientId);
connectBtn.innerText = "Connected";
});
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Subscribe to the topic
function onSub() {
if (client.connected) {
const { topic, qos } = subscriber;
client.subscribe(
topic.value,
{ qos: parseInt(qos.value, 10) },
(error, res) => {
if (error) {
console.error("Subscribe error: ", error);
} else {
console.log("Subscribed: ", res);
}
}
);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Unsubscribe
function onUnsub() {
if (client.connected) {
const { topic } = subscriber;
client.unsubscribe(topic.value, (error) => {
if (error) {
console.error("Unsubscribe error: ", error);
} else {
console.log("Unsubscribed: ", topic.value);
}
});
}
}
2
3
4
5
6
7
8
9
10
11
12
# Publish messages
function onSend() {
if (client.connected) {
const { topic, qos, payload } = publisher;
client.publish(topic.value, payload.value, {
qos: parseInt(qos.value, 10),
retain: false,
});
}
}
2
3
4
5
6
7
8
9
# Receive messages
// In the onConnect function
client.on("message", (topic, message) => {
const msg = document.createElement("div");
msg.setAttribute("class", "message-body");
msg.innerText = `${message.toString()}\nOn topic: ${topic}`;
document.getElementById("article").appendChild(msg);
});
2
3
4
5
6
7
# Disconnect
function onDisconnect() {
if (client.connected) {
client.end();
client.on("close", () => {
connectBtn.innerText = "Connect";
console.log(options.clientId + " disconnected");
});
}
}
2
3
4
5
6
7
8
9
# Test
At this point, we test the sending and receiving of messages with a MQTT 5.0 client tool - MQTT X (opens new window), also written in Electron.
When using MQTT X to send a message to the client, you can see that the message is received properly:
Send a message to MQTT X using the client you wrote yourself, and now you can see that MQTT X is also receiving the message properly:
# More
So far, we have completed that use Electron to create a simple MQTT desktop client, and simulate the connection, messaging, unsubscribe and disconnect scenarios between the client and MQTT broker. It is also worth noting that since the Electron project includes both a browser environment and a Node.js environment, it is possible to use the browser's WebSocket API to implement an MQTT over WebSocket connection by modifying the connection protocol and port number in the above code.
You can download the source code of the example here (opens new window), and you can also find more demo examples in other languages on GitHub (opens new window).