Freigeben über


Lernprogramm – Verwenden von MQTT zum Entwickeln eines IoT-Geräteclients ohne Verwendung eines Geräte-SDK

Sie sollten eine der Azure IoT-Geräte-SDKs verwenden, um Ihre IoT-Geräteclients zu erstellen, falls möglich. In Szenarien wie der Verwendung eines eingeschränkten Speichergeräts müssen Sie möglicherweise eine MQTT-Bibliothek verwenden, um mit Ihrem IoT-Hub zu kommunizieren.

Die Beispiele in diesem Lernprogramm verwenden die Eclipse Mosquitto MQTT-Bibliothek.

In diesem Tutorial erfahren Sie, wie:

  • Erstellen Sie die C-Sprachgeräte-Clientbeispielanwendungen.
  • Führen Sie ein Beispiel aus, das die MQTT-Bibliothek zum Senden von Telemetrie verwendet.
  • Führen Sie ein Beispiel aus, das die MQTT-Bibliothek verwendet, um eine vom IoT-Hub gesendete Cloud-zu-Gerät-Nachricht zu verarbeiten.
  • Führen Sie ein Beispiel aus, das die MQTT-Bibliothek verwendet, um den Gerätezwilling auf dem Gerät zu verwalten.

Sie können entweder einen Windows- oder Linux-Entwicklungscomputer verwenden, um die Schritte in diesem Lernprogramm auszuführen.

Wenn Sie noch kein Azure-Abonnement haben, erstellen Sie ein kostenloses Konto, bevor Sie beginnen.

Voraussetzungen

Voraussetzungen für Entwicklungscomputer

  1. Installieren Sie Visual Studio (Community, Professional oder Enterprise). Achten Sie darauf, die Desktopentwicklung mit C++ -Workload zu aktivieren.

  2. Installieren Sie CMake. Aktivieren Sie die Option CMake zum System-Path für alle Benutzer hinzufügen.

  3. Installieren Sie die x64-Version von Mosquitto.

Vorbereiten der Umgebung für die Azure CLI

Richten Sie Ihre Umgebung ein

Wenn Sie noch nicht über einen IoT-Hub verfügen, führen Sie die folgenden Befehle aus, um einen IoT-Hub im kostenlosen Tarif in einer Ressourcengruppe mit dem Namen mqtt-sample-rg zu erstellen. Der Befehl verwendet den Namen my-hub als Beispiel für den Namen des Zu erstellenden IoT-Hubs. Wählen Sie einen eindeutigen Namen für Ihren IoT-Hub, der an die Stelle von my-hub tritt.

az group create --name mqtt-sample-rg --location eastus
az iot hub create --name my-hub --resource-group mqtt-sample-rg --sku F1 

Notieren Sie sich den Namen Ihres IoT-Hubs, den Sie später benötigen.

Registrieren Sie ein Gerät in Ihrem IoT-Hub. Mit dem folgenden Befehl wird ein Gerät namens mqtt-dev-01 in einem IoT-Hub mit dem Namen my-hub registriert. Achten Sie darauf, den Namen Ihres IoT-Hubs zu verwenden:

az iot hub device-identity create --hub-name my-hub --device-id mqtt-dev-01

Verwenden Sie den folgenden Befehl, um ein SAS-Token zu erstellen, das dem Gerät Zugriff auf Ihren IoT-Hub gewährt. Achten Sie darauf, den Namen Ihres IoT-Hubs zu verwenden:

az iot hub generate-sas-token --device-id mqtt-dev-01 --hub-name my-hub --du 7200

Notieren Sie sich das SAS-Token, das von der Befehlsausgabe generiert wird, da Sie es später noch benötigen. Das SAS-Token sieht wie folgt aus: SharedAccessSignature sr=my-hub.azure-devices.net%2Fdevices%2Fmqtt-dev-01&sig=%2FnM...sNwtnnY%3D&se=1677855761

Tipp

Standardmäßig ist das SAS-Token 60 Minuten gültig. Die --du 7200 Option im vorherigen Befehl erweitert die Tokendauer auf zwei Stunden. Wenn sie abläuft, bevor Sie es verwenden können, generieren Sie eine neue. Sie können auch ein Token mit einer längeren Dauer erstellen. Weitere Informationen finden Sie unter az iot hub generate-sas-token.

Von Bedeutung

Dieser Artikel enthält Schritte zum Verbinden eines Geräts mithilfe einer Shared Access Signature, was auch als symmetrische Schlüsselauthentifizierung bezeichnet wird. Diese Authentifizierungsmethode eignet sich für Tests und Auswertungen, aber die Authentifizierung eines Geräts mit X.509-Zertifikaten ist ein sichererer Ansatz. Weitere Informationen finden Sie unter "Bewährte Methoden für Sicherheit von IoT-Lösungen > für die Verbindungssicherheit".

Klonen des Beispiel-Repositorys

Verwenden Sie den folgenden Befehl, um das Beispiel-Repository an einen geeigneten Speicherort auf Ihrem lokalen Computer zu klonen:

git clone https://github.com/Azure-Samples/IoTMQTTSample.git

Das Repository umfasst auch:

  • Ein Python-Beispiel, das die paho-mqtt Bibliothek verwendet.
  • Anweisungen für die Verwendung der mosquitto_pub CLI für die Interaktion mit Ihrem IoT-Hub.

Erstellen der C-Beispiele

Bevor Sie das Beispiel erstellen, müssen Sie die IoT-Hub- und Gerätedetails hinzufügen. Öffnen Sie im geklonten IoTMQTTSample-Repository die Datei mosquitto/src/config.h . Fügen Sie Ihren IoT-Hubnamen, Die Geräte-ID und das SAS-Token wie folgt hinzu. Achten Sie darauf, den Namen Ihres IoT-Hubs zu verwenden:

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#define IOTHUBNAME "my-hub"
#define DEVICEID   "mqtt-dev-01"
#define SAS_TOKEN  "SharedAccessSignature sr=my-hub.azure-devices.net%2Fdevices%2Fmqtt-dev-01&sig=%2FnM...sNwtnnY%3D&se=1677855761"

#define CERTIFICATEFILE CERT_PATH "IoTHubRootCA.crt.pem"

Hinweis

Die Datei "IoTHubRootCA.crt.pem " enthält die Zertifizierungsstelle-Stammzertifikate für die TLS-Verbindung.

Speichern Sie die Änderungen an der Datei mosquitto/src/config.h .

Führen Sie um die Samples zu erstellen die folgenden Befehle in der Shell aus.

cd mosquitto
cmake -Bbuild
cmake --build build

Unter Linux befinden sich die Binärdateien im Ordner ./build unter dem Mosquitto-Ordner .

In Windows befinden sich die Binärdateien im Ordner ".\build\Debug " unterhalb des Mosquitto-Ordners .

Senden von Telemetriedaten

Im mosquitto_telemetry Beispiel wird gezeigt, wie Sie mithilfe der MQTT-Bibliothek eine Geräte-zu-Cloud-Telemetrienachricht an Ihren IoT-Hub senden.

Führen Sie vor dem Ausführen der Beispielanwendung den folgenden Befehl aus, um den Ereignismonitor für Ihren IoT-Hub zu starten. Achten Sie darauf, den Namen Ihres IoT-Hubs zu verwenden:

az iot hub monitor-events --hub-name my-hub

Führen Sie das mosquitto_telemetry Beispiel aus. Beispiel: unter Linux:

./build/mosquitto_telemetry

Die az iot hub monitor-events generiert die folgende Ausgabe, die das vom Gerät gesendete Datenpaket anzeigt.

Starting event monitor, use ctrl-c to stop...
{
    "event": {
        "origin": "mqtt-dev-01",
        "module": "",
        "interface": "",
        "component": "",
        "payload": "Bonjour MQTT from Mosquitto"
    }
}

Sie können jetzt den Ereignismonitor beenden.

Überprüfen des Codes

Die folgenden Codeausschnitte stammen aus der Datei mosquitto/src/mosquitto_telemetry.cpp .

Die folgenden Anweisungen definieren die Verbindungsinformationen und den Namen des MQTT-Themas, das Sie zum Senden der Telemetrienachricht verwenden:

#define HOST IOTHUBNAME ".azure-devices.net"
#define PORT 8883
#define USERNAME HOST "/" DEVICEID "/?api-version=2020-09-30"

#define TOPIC "devices/" DEVICEID "/messages/events/"

Die main Funktion legt den Benutzernamen und das Kennwort für die Authentifizierung bei Ihrem IoT-Hub fest. Das Kennwort ist das SAS-Token, das Sie für Ihr Gerät erstellt haben:

mosquitto_username_pw_set(mosq, USERNAME, SAS_TOKEN);

Im Beispiel wird das MQTT-Thema verwendet, um eine Telemetrienachricht an Ihren IoT-Hub zu senden:

int msgId  = 42;
char msg[] = "Bonjour MQTT from Mosquitto";

// once connected, we can publish a Telemetry message
printf("Publishing....\r\n");
rc = mosquitto_publish(mosq, &msgId, TOPIC, sizeof(msg) - 1, msg, 1, true);
if (rc != MOSQ_ERR_SUCCESS)
{
    return mosquitto_error(rc);
}
printf("Publish returned OK\r\n");

Weitere Informationen finden Sie unter Senden von Geräte-zu-Cloud-Nachrichten.

Empfangen einer Cloud-zu-Gerät-Nachricht

Das mosquitto_subscribe Beispiel zeigt, wie Sie MQTT-Themen abonnieren und mithilfe der MQTT-Bibliothek eine Cloud-to-Device-Nachricht von Ihrem IoT-Hub erhalten.

Führen Sie das mosquitto_subscribe Beispiel aus. Beispiel: unter Linux:

./build/mosquitto_subscribe

Führen Sie den folgenden Befehl aus, um eine Cloud-to-Device-Nachricht von Ihrem IoT-Hub zu senden. Achten Sie darauf, den Namen Ihres IoT-Hubs zu verwenden:

az iot device c2d-message send --hub-name my-hub --device-id mqtt-dev-01 --data "hello world"

Die Ausgabe aus mosquitto_subscribe sieht wie im folgenden Beispiel aus:

Waiting for C2D messages...
C2D message 'hello world' for topic 'devices/mqtt-dev-01/messages/devicebound/%24.mid=d411e727-...f98f&%24.to=%2Fdevices%2Fmqtt-dev-01%2Fmessages%2Fdevicebound&%24.ce=utf-8&iothub-ack=none'
Got message for devices/mqtt-dev-01/messages/# topic

Überprüfen des Codes

Die folgenden Codeausschnitte stammen aus der Datei mosquitto/src/mosquitto_subscribe.cpp .

Die folgende Anweisung definiert den Themenfilter, den das Gerät zum Empfangen von Cloud- und Gerätenachrichten verwendet. # ist ein Mehrebenen-Platzhalter:

#define DEVICEMESSAGE "devices/" DEVICEID "/messages/#"

Die main Funktion verwendet die mosquitto_message_callback_set Funktion, um einen Rückruf festzulegen, um Nachrichten zu verarbeiten, die von Ihrem IoT-Hub gesendet werden, und verwendet die mosquitto_subscribe Funktion, um alle Nachrichten zu abonnieren. Der folgende Codeausschnitt zeigt die Rückruffunktion:

void message_callback(struct mosquitto* mosq, void* obj, const struct mosquitto_message* message)
{
    printf("C2D message '%.*s' for topic '%s'\r\n", message->payloadlen, (char*)message->payload, message->topic);

    bool match = 0;
    mosquitto_topic_matches_sub(DEVICEMESSAGE, message->topic, &match);

    if (match)
    {
        printf("Got message for " DEVICEMESSAGE " topic\r\n");
    }
}

Weitere Informationen finden Sie unter Verwendung von MQTT zum Empfangen von Cloud-zu-Gerät-Nachrichten.

Aktualisieren eines Gerätezwillings

Das mosquitto_device_twin Beispiel zeigt, wie eine gemeldete Eigenschaft in einem Geräte-Twin festgelegt und dann die Eigenschaft zurückgelesen wird.

Führen Sie das mosquitto_device_twin Beispiel aus. Beispiel: unter Linux:

./build/mosquitto_device_twin

Die Ausgabe von mosquitto_device_twin sieht wie im folgenden Beispiel aus:

Setting device twin reported properties....
Device twin message '' for topic '$iothub/twin/res/204/?$rid=0&$version=2'
Setting device twin properties SUCCEEDED.

Getting device twin properties....
Device twin message '{"desired":{"$version":1},"reported":{"temperature":32,"$version":2}}' for topic '$iothub/twin/res/200/?$rid=1'
Getting device twin properties SUCCEEDED.

Überprüfen des Codes

Die folgenden Codeausschnitte stammen aus der Datei mosquitto/src/mosquitto_device_twin.cpp .

Die folgenden Anweisungen definieren die Themen, die das Gerät zum Abonnieren von Gerätezwillingsupdates, zum Lesen des Gerätezwillingen und zum Aktualisieren des Gerätezwillings verwendet:

#define DEVICETWIN_SUBSCRIPTION  "$iothub/twin/res/#"
#define DEVICETWIN_MESSAGE_GET   "$iothub/twin/GET/?$rid=%d"
#define DEVICETWIN_MESSAGE_PATCH "$iothub/twin/PATCH/properties/reported/?$rid=%d"

Die main Funktion verwendet die mosquitto_connect_callback_set Funktion zum Festlegen eines Rückrufs zum Behandeln von Nachrichten, die von Ihrem IoT-Hub gesendet werden, und verwendet die mosquitto_subscribe Funktion zum Abonnieren des $iothub/twin/res/# Themas.

Der folgende Codeausschnitt zeigt die connect_callback-Funktion, die mosquitto_publish verwendet, um eine gemeldete Eigenschaft im Gerätezwilling festzulegen. Das Gerät veröffentlicht die Nachricht auf dem $iothub/twin/PATCH/properties/reported/?$rid=%d-Topic. Der %d Wert wird jedes Mal erhöht, wenn das Gerät eine Nachricht auf dem Topic veröffentlicht.

void connect_callback(struct mosquitto* mosq, void* obj, int result)
{
    // ... other code ...  

    printf("\r\nSetting device twin reported properties....\r\n");

    char msg[] = "{\"temperature\": 32}";
    char mqtt_publish_topic[64];
    snprintf(mqtt_publish_topic, sizeof(mqtt_publish_topic), DEVICETWIN_MESSAGE_PATCH, device_twin_request_id++);

    int rc = mosquitto_publish(mosq, NULL, mqtt_publish_topic, sizeof(msg) - 1, msg, 1, true);
    if (rc != MOSQ_ERR_SUCCESS)

    // ... other code ...  
}

Das Gerät abonniert das $iothub/twin/res/# Thema und wenn es eine Nachricht von Ihrem IoT-Hub empfängt, behandelt die message_callback Funktion es. Wenn Sie das Beispiel ausführen, wird die message_callback Funktion zweimal aufgerufen. Beim ersten Mal empfängt das Gerät eine Antwort vom IoT-Hub auf das gemeldete Eigenschaftenupdate. Das Gerät fordert dann den Twin des Geräts an. Beim zweiten Mal empfängt das Gerät den angeforderten Gerätezwilling. Der folgende Codeausschnitt zeigt die message_callback Funktion:

void message_callback(struct mosquitto* mosq, void* obj, const struct mosquitto_message* message)
{
    printf("Device twin message '%.*s' for topic '%s'\r\n", message->payloadlen, (char*)message->payload, message->topic);

    const char patchTwinTopic[] = "$iothub/twin/res/204/?$rid=0";
    const char getTwinTopic[]   = "$iothub/twin/res/200/?$rid=1";

    if (strncmp(message->topic, patchTwinTopic, sizeof(patchTwinTopic) - 1) == 0)
    {
        // Process the reported property response and request the device twin
        printf("Setting device twin properties SUCCEEDED.\r\n\r\n");

        printf("Getting device twin properties....\r\n");

        char msg[] = "{}";
        char mqtt_publish_topic[64];
        snprintf(mqtt_publish_topic, sizeof(mqtt_publish_topic), DEVICETWIN_MESSAGE_GET, device_twin_request_id++);

        int rc = mosquitto_publish(mosq, NULL, mqtt_publish_topic, sizeof(msg) - 1, msg, 1, true);
        if (rc != MOSQ_ERR_SUCCESS)
        {
            printf("Error: %s\r\n", mosquitto_strerror(rc));
        }
    }
    else if (strncmp(message->topic, getTwinTopic, sizeof(getTwinTopic) - 1) == 0)
    {
        // Process the device twin response and stop the client
        printf("Getting device twin properties SUCCEEDED.\r\n\r\n");

        mosquitto_loop_stop(mosq, false);
        mosquitto_disconnect(mosq); // finished, exit program
    }
}

Weitere Informationen finden Sie unter Verwenden von MQTT zum Aktualisieren einer gemeldeten Eigenschaft eines Gerätezwillings und Verwenden von MQTT zum Abrufen einer Gerätezwillingseigenschaft.

Bereinigen von Ressourcen

Wenn Sie weitere Artikel für Geräteentwickler verwenden möchten, können Sie die ressourcen, die Sie in diesem Artikel verwendet haben, beibehalten und wiederverwenden. Andernfalls können Sie die in diesem Artikel erstellten Ressourcen löschen, um weitere Gebühren zu vermeiden.

Sie können sowohl den Hub als auch das registrierte Gerät gleichzeitig löschen, indem Sie die gesamte Ressourcengruppe mit dem folgenden Azure CLI-Befehl löschen. Verwenden Sie diesen Befehl nicht, wenn diese Ressourcen eine Ressourcengruppe für andere Ressourcen freigeben, die Sie behalten möchten.

az group delete --name <YourResourceGroupName>

Um nur den IoT-Hub zu löschen, führen Sie den folgenden Befehl mit Azure CLI aus:

az iot hub delete --name <YourIoTHubName>

Um nur die Geräteidentität zu löschen, die Sie bei Ihrem IoT-Hub registriert haben, führen Sie den folgenden Befehl mit Azure CLI aus:

az iot hub device-identity delete --hub-name <YourIoTHubName> --device-id <YourDeviceID>

Möglicherweise möchten Sie auch die geklonten Beispieldateien von Ihrem Entwicklungscomputer entfernen.

Nächste Schritte

Nachdem Sie nun gelernt haben, wie Sie die Mosquitto MQTT-Bibliothek für die Kommunikation mit IoT Hub verwenden, besteht ein vorgeschlagener nächster Schritt darin, die MQTT-Anwendungsbeispiele auf GitHub zu überprüfen.