comunicacion-mqtt-nodejs

Cómo hacer comunicaciones MQTT con Node.js

MQTT (Message Queuing Telemetry Transport) es un protocolo de mensajería ligero, basado en el modelo de publicación/suscripción (publish/subscribe), diseñado para dispositivos con ancho de banda limitado y conexiones inestables.

Es ideal para aplicaciones donde se requiere una comunicación eficiente y escalable, como en el IoT (Internet of Things), sistemas de monitorización en tiempo real o aplicaciones móviles, entre otros.

Algunas de sus características son:

  • Ligero y eficiente: MQTT utiliza un formato de mensaje sencillo y de pequeño tamaño, que lo hace adecuado para dispositivos con recursos limitados.
  • Modelo de Publicación/Suscripción: Los clientes pueden publicar mensajes en un tema (topic) y suscribirse a temas para recibir mensajes relevantes.
  • QoS (Quality of Service): MQTT admite diferentes niveles de QoS para garantizar la entrega de mensajes según la importancia y la confiabilidad requerida.

Ejemplo de implementación de MQTT en Node.js

Para implementar MQTT en Node.js, utilizaremos la biblioteca mqtt que nos proporciona todas las herramientas necesarias para crear clientes y servidores MQTT.

Primero, necesitamos instalar la biblioteca mqtt en nuestro proyecto Node.js:

npm install mqtt

A continuación, veremos un ejemplo básico de cómo crear un servidor MQTT y cómo conectar clientes para enviar y recibir mensajes.

Creación de un cliente MQTT

import mqtt from 'mqtt';

// Conexión al broker MQTT
const client = mqtt.connect('mqtt://localhost:1883'); // Cambia por tu URL y puerto del broker

// Evento cuando se conecta al broker
client.on('connect', () => {
  console.log('Conectado al broker MQTT');

  // Suscribirse a un tema
  client.subscribe('mi/tema', (err) => {
    if (!err) {
      console.log('Suscrito al tema "mi/tema"');
    }
  });

  // Publicar un mensaje en un tema
  client.publish('mi/tema', 'Hola desde el cliente MQTT');
});

// Evento cuando se recibe un mensaje en el tema suscrito
client.on('message', (topic, message) => {
  console.log('Mensaje recibido en el tema:', topic);
  console.log('Contenido del mensaje:', message.toString());
});

// Manejo de errores
client.on('error', (err) => {
  console.error('Error en el cliente MQTT:', err);
});

En este ejemplo:

  • Se conecta al broker MQTT en mqtt://localhost:1883. Asegúrate de cambiar esto por la URL y puerto del broker MQTT al que te estás conectando.
  • Una vez conectado, se suscribe al tema 'mi/tema'.
  • Publica un mensaje en el mismo tema.
  • Cuando se recibe un mensaje en el tema suscrito, lo muestra por consola.

Cliente MQTT (solo Publicador)

Si solo os interesa publicar mensajes, aquí tenéis un ejemplo simplificado de un cliente que publica mensajes en el tema temperatura.

import mqtt from 'mqtt';

const client = mqtt.connect('mqtt://localhost:1883');

client.on('connect', () => {
  console.log('Conexión establecida');
  setInterval(() => {
    const temperatura = Math.floor(Math.random() * 50); // Generar temperatura aleatoria
    client.publish('temperatura', temperatura.toString());
    console.log(`Mensaje publicado en "temperatura": ${temperatura}`);
  }, 5000); // Publicar cada 5 segundos
});

client.on('error', (error) => {
  console.error('Error de conexión:', error);
});

En este ejemplo, creamos un cliente MQTT que se conecta al servidor local en el puerto 1883. Luego, publicamos mensajes aleatorios de temperatura en el tema temperatura cada 5 segundos.

Cliente MQTT (solo suscriptor)

Por otro lado, si sólo os interesa suscribirlos a un tema, aquí tenéis un ejemplo simplificado que se susbribe al topic temperatura para recibir y mostrar los mensajes.

const mqtt = require('mqtt');

const client = mqtt.connect('mqtt://localhost:1883');

client.on('connect', () => {
  console.log('Conexión establecida');
  client.subscribe('temperatura');
});

client.on('message', (topic, message) => {
  console.log(`Mensaje recibido en ${topic}: ${message.toString()}°C`);
});

Este cliente se conecta al mismo servidor MQTT y se suscribe al tema temperatura. Cada vez que llega un mensaje a este tema, lo muestra en la consola junto con la temperatura recibida.

Cliente Web MQTT

Vamos a ver cómo podríamos hacer un cliente Web con con HTML, JavaScript y la biblioteca Paho MQTT para comunicarnos por MQTT en el navegador.

Primero, asegúrate de incluir la biblioteca Paho MQTT en tu página web. Puedes hacerlo incluyendo el siguiente script en tu HTML,

<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.2.2/mqttws31.min.js"></script>

Luego, aquí tienes un ejemplo de cómo podría ser la página web,

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Cliente MQTT en la Web</title>  
</head>
<body>
  <h1>Cliente MQTT en la Web</h1>
  <div id="messages"></div>

  <script src="./paho-mqtt.min.js" integrity="sha512-Y5n0fbohPllOQ21fTwM/h9sQQ/1a1h5KhweGhu2zwD8lAoJnTgVa7NIrFa1bRDIMQHixtyuRV2ubIx+qWbGdDA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  
  <script>
    // Crear un cliente MQTT
    const client = new Paho.Client('localhost', 1833, 'web_client');

    // Función para mostrar mensajes en la página
    function displayMessage(topic, message) {
      const messagesDiv = document.getElementById('messages');
      const messageElement = document.createElement('p');
      messageElement.textContent = `Tema: ${topic}, Mensaje: ${message}`;
      messagesDiv.appendChild(messageElement);
    }

    // Callback cuando el cliente se conecta
    function onConnect() {
      console.log('Conectado al broker MQTT desde la web');
      client.subscribe('mi/tema');
    }

    // Callback cuando llega un mensaje
    function onMessageArrived(message) {
      console.log('Mensaje recibido:', message.destinationName, message.payloadString);
      displayMessage(message.destinationName, message.payloadString);
    }

    // Callback cuando hay un error
    function onFailure(message) {
      console.error('Error en la conexión:', message.errorMessage);
    }

    // Configurar los callbacks
    client.onConnectionLost = onFailure;
    client.onMessageArrived = onMessageArrived;

    // Conectar al broker
    client.connect({ onSuccess: onConnect });

    // Publicar un mensaje cuando se haga clic en un botón (solo como ejemplo)
    function publishMessage() {
      const message = 'Hola desde la web MQTT';
      const topic = 'mi/tema';
      const messageObj = new Paho.Message(message);
      messageObj.destinationName = topic;
      client.send(messageObj);
    }
  </script>

  <!-- Botón de ejemplo para publicar un mensaje -->
  <button onclick="publishMessage()">Publicar Mensaje</button>

  
</body>
</html>

En este ejemplo:

  • Se crea un cliente MQTT usando new Paho.MQTT.Client(), especificando la dirección del servidor y el puerto.
  • Se definen las funciones de callback onConnect, onMessageArrived, y onFailure para manejar la conexión, mensajes recibidos y errores respectivamente.
  • Cuando el cliente se conecta, se suscribe al tema 'mi/tema'.
  • Cuando llega un mensaje, se muestra en la página utilizando la función displayMessage.
  • El botón “Publicar Mensaje” envía un mensaje al tema 'mi/tema' cuando se hace clic.

Recuerda ajustar la dirección y el puerto del servidor MQTT en new Paho.MQTT.Client() según la configuración de tu broker MQTT.

Descarga el código

Todo el código de esta entrada está disponible para su descarga en Github github-full