Stellen Sie mit Websocket eine Verbindung zum MQTT-Broker her

In den letzten Jahren tauchen mit der rasanten Entwicklung des Web-Frontends ständig neue Funktionen von Browsern auf, während immer mehr Anwendungen browserseitig durch die Browser-Rendering-Engine implementiert werden können. Weit verbreitet ist auch WebSocket, die Instant-Kommunikationsmethode für Webanwendungen.

WebSocket ist ein Computerkommunikationsprotokoll, das Vollduplex-Kommunikationskanäle über eine einzige TCP-Verbindung bereitstellt. Das WebSocket-Protokoll wurde 2011 von der IETF als RFC 6455 standardisiert, und die WebSocket-API in Web IDL wird vom W3C standardisiert.

Kapitel 6 des MQTT-Protokolls legt die Bedingungen fest, die MQTT für die Übertragung über den WebSocket erfüllen muss [RFC6455] Verbindung und wird hier nicht im Detail besprochen.

Vergleich zweier Clients

Paho.mqtt.js

Übertragung ist ein MQTT-Client-Projekt von Eclipse, und der Paho-JavaScript-Client ist eine der browserbasierten Bibliotheken, die WebSockets verwendet, um eine Verbindung zum MQTT-Server herzustellen. Im Vergleich zu einer anderen JavaScript-Verbindungsbibliothek hat sie weniger Funktionen und wird nicht empfohlen.

MQTT.js

MQTT.js ist eine vollständig quelloffene clientseitige Bibliothek für das MQTT-Protokoll, die in JavaScript geschrieben und für Node.js und Browser verfügbar ist. Auf Node.js-Seite kann es über die globale Installation installiert und über die Kommandozeile verbunden werden. Außerdem unterstützt es MQTT/TCP-, MQTT/TLS-, MQTT/WebSocket-Verbindungen. Erwähnenswert ist, dass MQTT.js auch das WeChat Mini-Programm gut unterstützt.

In diesem Artikel wird die MQTT.js-Bibliothek verwendet, um WebSocket-Verbindungen zu erläutern.

Installieren Sie MQTT.js

Wenn Sie die Node.js-Laufzeitumgebung auf Ihrem Computer haben, können Sie MQTT.js direkt mit dem Befehl npm installieren.

Im aktuellen Verzeichnis installieren

npm install mqtt --save

CDN-Referenzen

Oder verwenden Sie CDN-Adressen direkt ohne Installation

<script src="

<script>
    // Globally initializes an mqtt variable
    console.log(mqtt)
</script>

Verbinden Sie sich mit dem MQTT-Broker

Dieser Artikel verwendet die kostenloser öffentlicher MQTT-Broker bereitgestellt von EMQX. Dieser Dienst wurde auf Basis des EMQX erstellt MQTT-IoT-Cloud-Plattform. Die Informationen zum Maklerzugang lauten wie folgt:

  • Makler: broker.emqx.io
  • TCP-Port: 1883
  • Websocket-Port: 8083

EMQX verwendet Port 8083 für normale Verbindungen und 8084 für WebSocket über TLS.

Lassen Sie uns der Einfachheit halber den Abonnenten und den Herausgeber in dieselbe Datei einfügen.

const clientId = 'mqttjs_' + Math.random().toString(16).substr(2, 8)

const host="ws://broker.emqx.io:8083/mqtt"

const options = {
  keepalive: 60,
  clientId: clientId,
  protocolId: 'MQTT',
  protocolVersion: 4,
  clean: true,
  reconnectPeriod: 1000,
  connectTimeout: 30 * 1000,
  will: {
    topic: 'WillMsg',
    payload: 'Connection Closed abnormally..!',
    qos: 0,
    retain: false
  },
}

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...')
})

Verbindungsadresse

Die oben gezeigte Linkadresse kann aufgeteilt werden in: ws: // broker . emqx.io : 8083 /mqtt

Das ist protocol // host name . domain : port / path

Anfänger machen wahrscheinlich die folgenden Fehler.

  • Die Verbindungsadresse gibt kein Protokoll an: WebSocket ist ein Kommunikationsprotokoll, das verwendet ws (unverschlüsselt), wss (SSL-verschlüsselt) als Protokollkennung. Der MQTT.js-Client unterstützt mehrere Protokolle und die Verbindungsadresse muss den Protokolltyp angeben.
  • Die Verbindungsadresse gibt keinen Port an: MQTT gibt keinen Port für den WebSocket-Zugriff an, und EMQX verwendet 8083 und 8084 als Standardports für unverschlüsselte bzw. verschlüsselte Verbindungen. Der Standardport des WebSocket-Protokolls ist derselbe wie HTTP (80/443), kein Port bedeutet, dass WebSocket den Standardport für die Verbindung verwendet. Andererseits muss bei Verwendung einer Standard-MQTT-Verbindung kein Port angegeben werden. Beispielsweise kann MQTT.js verwendet werden mqtt://localhost auf der Node.js-Seite, um sich mit dem Standard-MQTT 1883-Port zu verbinden, und wenn die Verbindungsadresse lautet mqtts://localhostwird es mit dem Port 8884 verbunden.
  • Verbindungsadresse ohne Pfad: MQTT-WebSoket verwendet einheitlich /path B. der Verbindungspfad, der beim Verbinden angegeben werden sollte, und der Pfad, der auf EMQX verwendet wird /mqtt.
  • Das Protokoll passt nicht zum Port: use wss Verbindung, aber mit Port verbinden 8083.
  • Die Verwendung von unverschlüsselten WebSocket-Verbindungen unter HTTPS: Organisationen wie Google forcieren HTTPS und schränken gleichzeitig die Sicherheit durch Browsereinschränkungen ein, dh die Verwendung von unverschlüsselten Verbindungen ws Protokoll zum Initiieren von Verbindungsanfragen wird vom Browser bei HTTPS-Verbindungen automatisch unterbunden.
  • Das Zertifikat stimmt nicht mit der Verbindungsadresse überein: lang, Details siehe unten Aktivieren Sie SSL/TLS für EMQX.

Verbindungsoptionen

Im obigen Code options sind die Client-Verbindungsoptionen. Im Folgenden finden Sie die Beschreibung der Hauptparameter, die restlichen Parameter siehe https://github.com/mqttjs/MQTT.js#client.

  • Keepalive: Heartbeat-Zeit, Standard 60 Sekunden, 0 auf deaktiviert setzen.
  • clientId: Client-ID, die zufällig generiert wird von'mqttjs_' + Math.random().toString(16).substr(2, 8) standardmäßig.
  • Benutzername: Verbindungsbenutzername (optional)
  • Passwort: Verbindungspasswort (optional)
  • clean: true, auf false setzen, um QoS 1- und 2-Nachrichten offline zu empfangen.
  • reconnectPeriod: Standard 1000 Millisekunden, das Intervall zwischen Wiederverbindungen, Client-ID-Duplikaten, Authentifizierungsfehlern usw. Der Client stellt die Verbindung wieder her.
  • connectTimeout: Standard 30 * 1000 Millisekunden, die Wartezeit, bevor CONNACK empfangen wird, dh die Timeout-Zeit der Verbindung.
  • will: will message, die Nachricht, die der Broker automatisch sendet, wenn ein Client ernsthaft getrennt wird. Das allgemeine Format ist:
    • Thema: Das Thema, das veröffentlicht werden soll
    • Payload: die zu veröffentlichende Nachricht
    • qos: QoS
    • Beibehalten: Zeichen beibehalten

Abonnements können nur nach einer erfolgreichen Verbindung vorgenommen werden und die abonnierten Themen müssen den MQTT-Abonnement-Themenregeln entsprechen.

Hinweis: JavaScript Die asynchrone, nicht blockierende Funktion von JavaScript stellt eine erfolgreiche Verbindung nur nach dem Connect-Ereignis oder durch Verwendung sicher client.connected um festzustellen, ob die Verbindung erfolgreich war.

client.on('connect', () => {
  console.log('Client connected:' + clientId)
  // Subscribe
  client.subscribe('testtopic', { qos: 0 })
})
// Unsubscribe
client.unubscribe('testtopic', () => {
  console.log('Unsubscribed')
})

Nachrichten veröffentlichen/empfangen

Veröffentlichen Sie Nachrichten zu bestimmten Themen. Das veröffentlichte Thema muss die Regel des MQTT-Veröffentlichungsthemas erfüllen. Andernfalls wird die Verbindung getrennt. Sie müssen dieses Thema vor der Veröffentlichung nicht abonnieren, müssen jedoch sicherstellen, dass der Client bereits erfolgreich eine Verbindung hergestellt hat.

// Publish
client.publish('testtopic', 'ws connection demo...!', { qos: 0, retain: false })
// Received
client.on('message', (topic, message, packet) => {
  console.log('Received Message: ' + message.toString() + '\nOn topic: ' + topic)
})

WeChat-Miniprogramm

Die Bibliothek MQTT.js verwendet wxs Protokollkennung, um das WeChat Mini-Programm speziell zu verarbeiten. Hinweis: Die Applet-Entwicklungsspezifikation erfordert, dass eine verschlüsselte Verbindung verwendet werden muss und die Verbindungsadresse ähnlich sein sollte wxs://broker.emqx.io:8084/mqtt.

Aktivieren Sie SSL/TLS für EMQX

EMQ integriertes selbstsigniertes Zertifikat, verschlüsselte WebSocket-Verbindung wurde standardmäßig gestartet, aber die meisten Browser melden Fehler aufgrund ungültiger Zertifikate wie z net::ERR_CERT_COMMON_NAME_INVALID (Chrome, 360 und andere WebKit-Kernel-Browser im Entwicklermodus. Auf der Registerkarte „Konsole“ können die meisten Verbindungsfehler angezeigt werden). Der Grund für diesen Fehler ist, dass der Browser die Gültigkeit des selbstsignierten Zertifikats nicht überprüfen kann. Der Leser muss ein vertrauenswürdiges Zertifikat von einer Zertifizierungsstelle erwerben und sich für Konfigurationsaktionen auf den entsprechenden Abschnitt in diesem Artikel beziehen: Aktivieren Sie SSL/TLS für den EMQX MQTT-Broker.

Die Bedingungen, die zum Aktivieren von SSL/TLS-Zertifikaten erforderlich sind, sind hier zusammengefasst:

  • Binden Sie den Domänennamen an die öffentliche Adresse des MQTT-Brokers: Das von der Zertifizierungsstelle ausgestellte Zertifikat ist für den Domänennamen signiert.
  • Beantragen Sie ein Zertifikat: Beantragen Sie ein Zertifikat für den verwendeten Domänennamen bei einer Zertifizierungsstelle. Achten Sie darauf, eine zuverlässige Zertifizierungsstelle auszuwählen und dass das Zertifikat zwischen einem generischen Domänennamen und einem Hostnamen unterscheidet.
  • Wähle aus wss Protokoll bei Verwendung einer verschlüsselten Verbindung und Verwenden Sie den Domänennamen, um eine Verbindung herzustellen : Nach dem Binden des Domänennamens – Zertifizierung muss anstelle der IP-Adresse der Domänenname verwendet werden, um eine Verbindung herzustellen, damit der Browser die Zertifizierung gemäß dem Domänennamen überprüft, um eine Verbindung herzustellen, nachdem er die Prüfung bestanden hat.

EMQX-Konfiguration

Öffne das etc/emqx.conf Konfigurationsdatei und ändern Sie die folgenden Konfigurationen:

# wss listening address
listener.wss.external = 8084

# Modify key file address
listener.wss.external.keyfile = etc/certs/cert.key

# Modify certificate file address
listener.wss.external.certfile = etc/certs/cert.pem

Starten Sie EMQX nach Abschluss neu.

Sie können Ihr Zertifikat und Ihre Schlüsseldateien verwenden, um sie direkt unter etc/certs/ zu ersetzen.

Konfigurieren von Reverse-Proxys und Zertifikaten auf Nginx

Die Verwendung von Nginx zum Reverse-Proxy und zum Verschlüsseln von WebSocket kann die Rechenlast des EMQX-Brokers reduzieren und gleichzeitig das Multiplexing von Domänennamen implementieren. Nginx Lastverteilung ermöglicht es Ihnen auch, mehrere Back-End-Dienstentitäten zu verteilen.

# It is recommended that WebSocket also bind to port 443.
listen 443, 8084;
server_name example.com;

ssl on;

ssl_certificate /etc/cert.crt; # certificate path
ssl_certificate_key /etc/cert.key; # key path

# upstream server list
upstream emq_server {
    server 10.10.1.1:8883 weight=1;
    server 10.10.1.2:8883 weight=1;
    server 10.10.1.3:8883 weight=1;
}

# Common website application
location / {
    root www;
    index index.html;
}

# Reverse proxy to EMQX unencrypted WebSocket
location / {
    proxy_redirect off;
    # upstream
    proxy_pass 

    proxy_set_header Host $host;
    # Reverse proxy retains client address
    proxy_set_header X-Real_IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
    # WebSocket extra request header
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection “upgrade”;
}

Andere Ressourcen

Der vollständige Projektcode:

Ein Online-MQTT-WebSocket-Toolkit:

Ursprünglich erschienen bei

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *