Node.js y MQTT

JavaScript es uno de los lenguajes de programación que ha crecido exponencialmente en los últimos años, uno de los mayores salto fue la implementación de Node.js que permitía la posibilidad de ejecutar procesos del lado del servidor. Al ser un lenguaje ligero es posible instalar y ejecutar cosas en Node.js en casi cualquier dispositivo, desde un gran servidor hasta una pequeña placa como puede el Intel Edison o Arduino.
La comunicación entre dispositivos siempre a estado hay, con una gran variedad de protocolos que se adaptan a las necesidades de cada tarea. Entre todo MQTT es un protocolo de publicación y suscripción simple. Permitiendo enviar mensajes por canales (topics) mediante un servidor centralizado. Este protocolo es bastante ligero, lo que facilita la implementeación y ejecución en casi cualquier dispositivo.
Ejemplo MQTT

Ejemplo de comunicación MQTT

Usando estas 2 tecnologías (Node.js y MQTT) vamos a crear un sistema simple de comunicación entre dispositivos y un servidor MQTT usando únicamente Node.js.

Servidor

Para el servidor vamos a usar la librería «mosca» la cual esta preparada para este uso y cuenta con una serie de configuraciones extras, según el uso que necesitemos. Como configuraciones por defecto el puerto es el 1883 y la IP es «localhost». Ya que es el encargado de distribuir los mensajes, cuanta con una serie de eventos para detectar las interacciones con este:
  • clientConnected: Informa sobre la conexión de un servicio
  • clientDisconnected: Informa sobre la des-conexión de un servicio
  • subscribed: Informa sobre la suscripción de un servicio
  • unsubscribed: Informa sobre la des-suscripción de un servicio
  • published: Informa sobre la publicación de un mensaje
  • clientError: Informa sobre un error en la conexión o envión de un mensaje.
//server.js

const mosca = require('mosca');
const settings = {host: '127.0.0.1', port: 1883};
const server = new mosca.Server(settings);

server.on('ready', function() {
    console.info('MQTT server ready.');
});

server.on('clientConnected', function(client) {
    console.info('Client connect: %s', client.id);
});

server.on('clientDisconnected', function(client) {
    console.log('Client Disconnected:', client.id);
});

server.on('subscribed', (topic, client) => {
    console.info('Client subscribed: %s Topic suscribe: %s', client.id, topic);
});

server.on('unsubscribed', (topic, client) => {
    console.info('Client unsubscribed: %s Topic unsubscribed: %s', client.id, topic);
});

server.on('clientError', (topic, client) => {
    console.info('Client clientError: ', client, topic);
});

server.on('published', (packet, client) => {
    if (client !== undefined) {
        console.info('Client Publish: %s Topic publish: %s', client.id, packet.topic);
    }
});

Con script en JS tenemos todo lo necesario para crear un pequeño servidor MQTT que se puede ejecutar en por ejemplo un Arduino.

 

Publish

Para publicar o enviar mensajes, vamos a usar la librería «mqtt» la cual también se usara en el servicio de suscripción. Como requisitos mínimos de para enviar un mensaje nos pide una URL de conexión, la cual se compone de «mqtt://» (protocolo) mqtt.server (IP o dominio) y separado por : el puerto (si se usa el puerto por defecto no es necesario especificarlo) quedando como «mqtt://mqtt.server:1883«. Con esta URL tendríamos una conexión al servidor MQTT y estaríamos listos para enviar un mensaje.

Ahora tenemos que especificar el canal o topic al que vamos a enviar el mensaje, en este caso vamos a usar el canal «example/mqtt» el cual sera el mismo que tendrá el script de suscripción.

//publish.js

const mqttLocation = 'mqtt://mqtt.server:1883';
const mqttTopic = 'example/mqtt';
const mqtt = require('mqtt');

const client = mqtt.connect(mqttLocation);

client.on('connect', function(packet) {
    console.log('Connect Success')

    let message = new Buffer.from('New Message!');
    //let message = 'New String';

    client.publish(mqttTopic, message, (error) => {
        console.log(error || 'Publish Success');
        client.end();
    });
});

client.on('error', function (err) {
    console.log('Error: ', err);
});

 

Subscribe

Para el suscriptor sera necesario la misma librería JS, URL de conexión con el servidor y el canal que se usa en el script de «publish«. Este script se conectara al servidor MQTT y se suscribirá al canal «example/mqtt» para así recibir todos los mensajes que se envíen a este; De forma simple u ordenada es una buena practica que un script se suscriba a un solo canal, pero como tal se puede suscribir a todos los que necesite.

La recepción de los mensajes llegara al callback ‘message‘ que como primer parámetro estará el canal al que pertenece el mensaje y como segundo parámetro sera el mensaje dentro de un objeto Buffer.

//subscribe.js

const mqttLocation = 'mqtt://mqtt.server:1883';
const mqttTopic = 'example/mqtt';
const mqtt = require('mqtt');

const client = mqtt.connect(mqttLocation);

client.on('connect', function(packet) {
    console.log('Connect Success')

    client.subscribe(mqttTopic, (err) => {
        console.error(err || 'Subscribe Success')
    });
});

client.on('reconnect', (err) => {
    console.error(err || 'Reconnect');
});

client.on('message', (topic, message) => {
    console.log('Received form: %s message: %s', topic, message.toString())
});

client.on('error', function (err) {
    console.log('Error: ', err);
});

 

Ejecución

  1. Inicializamos el servidor MQTT «node server.js»
  2. Inicializamos el servicio de suscripción «node subscribe.js» que se conectara al servidor y se suscribirá al canal «example/mqtt»
  3. Ejecutamos el servicio de publicación «node publish.js» el cual se conectara al servidor y enviara nuestro mensaje al canal «example/mqtt»
  4. El servidor valida que servicios están suscritos a este canal y envía el mensaje.
  5. El servicio suscrito recibe el mensaje!!!

Este pequeño ejemplo nos permite explorar el funcionamiento de estas tecnologías, que pueden llegar a darnos grandes funcionalidades, como tener N ordenadores escuchando un canal al que les puede llegar la orden de apagar; O un suscriptor que espere la señal de N publicadores para persistir información en sistemas como Redis o MongoDB.

 

 

Ejemplo en github: https://git.irontec.com/internet/example-node-mqtt

 

URL de referencia:

  • https://www.npmjs.com/package/mqtt
  • https://www.npmjs.com/package/mosca
  • https://github.com/mqttjs



¿Te gusta este post? Es solo un ejemplo de cómo podemos ayudar a tu empresa...
Sobre Daniel Rendon Arias

Hola, soy Daniel. Un gran amigo de PHP.

Queremos tu opinión :)