{"id":1390,"date":"2022-03-19T22:55:57","date_gmt":"2022-03-19T21:55:57","guid":{"rendered":"https:\/\/nguenkam.com\/blog\/?p=1390"},"modified":"2022-03-19T22:55:57","modified_gmt":"2022-03-19T21:55:57","slug":"using-mqtt-on-angular-apps","status":"publish","type":"post","link":"https:\/\/nguenkam.com\/blog\/index.php\/2022\/03\/19\/using-mqtt-on-angular-apps\/","title":{"rendered":"Using MQTT on Angular Apps"},"content":{"rendered":"\n<p>When we are building a website that needs to be updated in real-time, our first thought is probably to add WebSockets to our application.<\/p>\n\n\n\n<p>However Websockets is a low-level protocol and to use it, we will need to add another layer on top to manage the information we want to get. This is where MQTT protocol is handy, as it\u2019s a higher-level protocol that simplifies working with data streams.<\/p>\n\n\n\n<h4>What is MQTT?<\/h4>\n\n\n\n<p>MQTT means Message Queuing Telemetry Transport. It\u2019s a connectivity protocol used in the IoT world to communicate between machines.<\/p>\n\n\n\n<h4>Architecture<\/h4>\n\n\n\n<p>An MQTT protocol ecosystem has the following components:<\/p>\n\n\n\n<ul><li><strong>Publisher:<\/strong>\u00a0Responsible for publishing MQTT messages to the system. Usually an IoT device.<\/li><li><strong>MQTT Broker:<\/strong>\u00a0The server that gets the published data and sends it to the corresponding subscribers.<\/li><li><strong>Subscriber:<\/strong>\u00a0The device that is listening for incoming data from devices.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/03\/image-6.png\" alt=\"\" class=\"wp-image-1751\" width=\"588\" height=\"213\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/03\/image-6.png 984w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/03\/image-6-300x109.png 300w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/03\/image-6-768x279.png 768w\" sizes=\"(max-width: 588px) 100vw, 588px\" \/><\/figure>\n\n\n\n<h4>Publish\/Subscribe Model<\/h4>\n\n\n\n<p>As we have seen in the architecture overview, MQTT uses the publish\/subscribe methodology. So they don\u2019t know each other, they just need to agree on how data is going to be sent. It also allows the use of multiple publishers or subscribers, so various clients can create an MQTT connection and subscribe to data from a single device.<\/p>\n\n\n\n<h4>MQTT Topics<\/h4>\n\n\n\n<p>An MQTT Topic is the concept used to communicate between publishers and subscribers. When a subscriber wants to get data from a device, it subscribes to a specific topic, which will be where the device publishes its data. A Topic is a hierarchical UTF-8 string, and here you have an example:   <em><strong> &#8220;local\/command\/mmi\/camera\/state&#8221;<\/strong><\/em><\/p>\n\n\n\n<h4>MQTT Over Websockets<\/h4>\n\n\n\n<p>MQTT is a high-level protocol and the great thing is that it can use different protocols to get its job done. It can adopt its own MQTT protocol, but this protocol is not supported by web browsers; however MQTT can also be used over WebSockets connection, so we can easily use MQTT on any web browser that supports WebSockets.<\/p>\n\n\n\n<h4>Which MQTT Broker Should I Use?<\/h4>\n\n\n\n<p>There are various MQTT brokers we can use for our project. On one hand we can use cloud\/hosted solutions; alternatively we can choose an on-premise option, either by installing on our own servers or using through Docker.<\/p>\n\n\n\n<p>You can see a comprehensive list of the existing brokers in\u00a0<a href=\"https:\/\/github.com\/mqtt\/mqtt.github.io\/wiki\/brokers\">this Github repo<\/a>. In our case we have used the open source\u00a0<a href=\"https:\/\/mosquitto.org\/\">Eclipse Mosquitto<\/a>\u00a0with great success.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-cyan-blue-color\">MQTT Client on Angular Apps<\/span><\/h4>\n\n\n\n<p>Now let\u2019s see how can we use MQTT protocol on an Angular app. The easiest way to do it is to use some of the existing Javascript libraries. In this case, we will use the\u00a0<a href=\"https:\/\/sclausen.github.io\/ngx-mqtt\/\">ngx-mqtt library<\/a>. This offers support for Javascript\/Typescript observables, so it\u2019s really helpful when writing an MQTT client on an Angular app.<\/p>\n\n\n\n<h4>Installing ngx-mqtt<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install ngx-mqtt --save<\/code><\/pre>\n\n\n\n<h4>Configuration<\/h4>\n\n\n\n<p>Once the library is installed, you need to initialize it. You can follow the instructions on the ngx-mqtt site, but you will probably have multiple environments in your Angular code, so you will need a different configuration for each environment. So let\u2019s create an\u00a0<strong>mqtt<\/strong>\u00a0section in our environment files. Here\u2019s an example:\u00a0<code>src\/environments\/environment.prod.ts<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export const environment = {\r\n  production: true,\r\n\thmr: false,\r\n\thttp: {\r\n\t\tapiUrl: '&lt;https:\/\/api.myweb.com>',\r\n\t},\r\n\tmqtt: {\r\n\t\tserver: 'mqtt.myweb.com',\r\n\t\tprotocol: \"wss\",\r\n\t\tport: 1883\r\n\t}\r\n};<\/code><\/pre>\n\n\n\n<p>You can edit all other environment configuration files to set the right values for each one. Now we need to initialize the MQTT library, and for this we recommend changing to\u00a0<code>app.module.ts<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\r\nimport { IMqttServiceOptions, MqttModule } from \"ngx-mqtt\";\r\nimport { environment as env } from '..\/environments\/environment';\r\n\r\nconst MQTT_SERVICE_OPTIONS: IMqttServiceOptions = {\r\n    hostname: env.mqtt.server,\r\n    port: env.mqtt.port,\r\n    protocol: (env.mqtt.protocol === \"wss\") ? \"wss\" : \"ws\",\r\n    path: '',\r\n};\r\n\r\n@NgModule({\r\n    declarations: &#91;AppComponent],\r\n    imports: &#91;\r\n        ...\r\n        MqttModule.forRoot(MQTT_SERVICE_OPTIONS),\r\n    ],\r\n    ...\r\n})\r\nexport class AppModule { }<\/code><\/pre>\n\n\n\n<h4>Creating Services<\/h4>\n\n\n\n<p>It is recommend to create a service class which manage the differents\u00a0<strong>Topic<\/strong>s\u00a0we are going to use. Let\u2019s create a service that subscribes to a topic , where the Topic name is similar to\u00a0<code>\/local\/data\/temperature<\/code>. For this we create the Typescript file\u00a0<code>src\/app\/services\/event.mqtt.service.ts<\/code> with the following code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { Injectable } from '@angular\/core';\r\nimport { IMqttMessage, MqttService } from \"ngx-mqtt\";\r\nimport { Observable } from \"rxjs\";\r\n\r\n@Injectable()\r\nexport class EventMqttService {\r\n\r\n  constructor(\rprivate _mqttService: MqttService)\n\n  topic(topicName: string): Observable&lt;IMqttMessage> {\r   \r\n    return this._mqttService.observe(topicName);\r\n  }\r\n}<\/code><\/pre>\n\n\n\n<p>Using this service class, we have all the MQTT-related code in a single file and now we only need to use this service when it\u2019s needed.<\/p>\n\n\n\n<p><em>PS: Remember to add all the services files to the\u00a0<strong>providers<\/strong>\u00a0section of your\u00a0<strong>AppModule,<\/strong>\u00a0otherwise you won\u2019t be able to use them.<\/em><\/p>\n\n\n\n<h4>Using the MQTT Services<\/h4>\n\n\n\n<p>Now it\u2019s time to use the MQTT services we have created. So, for example, let\u2019s create an\u00a0<strong>EventStream<\/strong>\u00a0component that prints all the events that a device generates. The code of this file will be similar to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { Component, OnInit } from '@angular\/core';\r\nimport { EventDataModel } from 'app\/models\/event.model';\r\nimport { Subscription } from 'rxjs';\r\nimport { EventMqttService } from 'app\/services\/api\/event.mqtt.service';\r\nimport { IMqttMessage } from \"ngx-mqtt\";\r\n\r\n@Component({\r\n    selector: 'event-stream',\r\n    templateUrl: '.\/event-stream.component.html',\r\n    styleUrls: &#91;'.\/event-stream.component.scss'],\r\n})\r\nexport class EventStreamComponent implements OnInit {\r\n    events: any&#91;];\r\n    private deviceId: string;\r\n    subscription: Subscription;\r\n\r\n    constructor(\r\n        private readonly eventMqtt: EventMqttService,\r\n    ) {\r\n    }\r\n\r\n    ngOnInit() {\r\n        this.subscribeToTopic();\r\n    }\r\n\r\n    ngOnDestroy(): void {\r\n        if (this.subscription) {\r\n            this.subscription.unsubscribe();\r\n        }\r\n    }\r\n\r\n    private subscribeToTopic() {\r\n        this.subscription = this.eventMqtt.topic(this.deviceId)\r\n            .subscribe((data: IMqttMessage) => {\r\n                let item = JSON.parse(data.payload.toString());\r\n\t\tthis.events.push(item);\r\n            });\r\n    }\r\n}<\/code><\/pre>\n\n\n\n<p>It\u2019s important to remember that we need to&nbsp;<strong>unsubscribe<\/strong>&nbsp;from the subscription when we destroy the component.<\/p>\n\n\n\n<p>Now, we should have an Angular app that can subscribe to MQTT topics and show the user the information every time a device generates an MQTT message.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h5>Reference:<\/h5>\n\n\n\n<p><a href=\"https:\/\/bugfender.com\/\">https:\/\/bugfender.com\/<\/a><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>When we are building a website that needs to be updated in real-time, our first thought is probably to add WebSockets to our application. However Websockets is a low-level protocol and to use it, we will need to add another layer on top to manage the information we want to get. This is where MQTT [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1391,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[37],"tags":[387,222,389,507,388,391,390],"_links":{"self":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1390"}],"collection":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=1390"}],"version-history":[{"count":3,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1390\/revisions"}],"predecessor-version":[{"id":1753,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1390\/revisions\/1753"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media\/1391"}],"wp:attachment":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=1390"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=1390"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=1390"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}