Share via


Oktatóanyag – Az MQTT használata IoT-eszközügyfél fejlesztéséhez eszköz SDK használata nélkül

Ha lehetséges, az Azure IoT-eszköz SDK-k egyikével hozhatja létre az IoT-eszköz ügyfeleit. Az olyan helyzetekben, mint például a memóriakorlátozott eszközök használata, előfordulhat, hogy MQTT-kódtárat kell használnia az IoT Hubbal való kommunikációhoz.

Az oktatóanyagban szereplő minták az Eclipse Mosquitto MQTT könyvtárat használják.

Ebben az oktatóanyagban az alábbiakkal fog megismerkedni:

  • Hozza létre a C nyelvi eszköz ügyfélalkalmazásainak mintaalkalmazását.
  • Futtasson egy mintát, amely az MQTT-kódtár használatával küld telemetriát.
  • Futtasson egy mintát, amely az MQTT-kódtárat használja az IoT Hubról küldött felhő-eszköz üzenet feldolgozásához.
  • Futtasson egy mintát, amely az MQTT-kódtár használatával kezeli az ikereszközt az eszközön.

Az oktatóanyag lépéseit Windows vagy Linux rendszerű fejlesztőgéppel is elvégezheti.

Ha még nincs Azure-előfizetése, kezdés előtt hozzon létre egy ingyenes fiókot.

Előfeltételek

A környezet előkészítése az Azure CLI-hez

A fejlesztési gép előfeltételei

Windows használata esetén:

  1. Telepítse a Visual Studiót (Community, Professional vagy Enterprise). Mindenképpen engedélyezze az asztali fejlesztést C++ számítási feladattal.

  2. Telepítse a CMake-t. Engedélyezze az Add CMake to the system PATH for all users option (CMake hozzáadása a rendszer ELÉRÉSI ÚTJÁN) beállítását.

  3. Telepítse a Mosquitto x64-es verzióját.

Linux használata esetén:

  1. Futtassa a következő parancsot a buildelési eszközök telepítéséhez:

    sudo apt install cmake g++
    
  2. Futtassa a következő parancsot a Mosquitto ügyfélkódtár telepítéséhez:

    sudo apt install libmosquitto-dev
    

Saját környezet beállítása

Ha még nincs IoT Hubja, futtassa az alábbi parancsokat egy ingyenes szintű IoT Hub létrehozásához egy úgynevezett mqtt-sample-rgerőforráscsoportban. A parancs példaként használja a nevet my-hub az IoT Hub létrehozásához. Válasszon egyedi nevet az IoT Hubnak a következő helyett my-hub:

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

Jegyezze fel az IoT Hub nevét, és később szüksége lesz rá.

Regisztráljon egy eszközt az IoT Hubon. Az alábbi parancs regisztrálja a hívott mqtt-dev-01 eszközt egy IoT Hub nevű my-hubközpontban. Mindenképpen használja az IoT Hub nevét:

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

Az alábbi paranccsal hozzon létre egy SAS-jogkivonatot, amely hozzáférést biztosít az eszköznek az IoT Hubhoz. Mindenképpen használja az IoT Hub nevét:

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

Jegyezze fel az SAS-jogkivonatot a parancskimenetekről, amint később szüksége lesz rá. Az SAS-jogkivonat a következőképpen néz ki SharedAccessSignature sr=my-hub.azure-devices.net%2Fdevices%2Fmqtt-dev-01&sig=%2FnM...sNwtnnY%3D&se=1677855761

Tipp.

Alapértelmezés szerint az SAS-jogkivonat 60 percig érvényes. Az --du 7200 előző parancsban megadott beállítás két órára meghosszabbítja a jogkivonat időtartamát. Ha a használat előtt lejár, hozzon létre egy újat. Hosszabb időtartamú jogkivonatot is létrehozhat. További információ: az iot hub generate-sas-token.

A mintaadattár klónozása

Az alábbi paranccsal klónozhatja a mintaadattárat egy megfelelő helyre a helyi gépen:

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

Az adattár a következőket is tartalmazza:

  • A kódtárat használó paho-mqtt Python-minta.
  • Útmutatás az IoT Hub használatához a mosquitto_pub parancssori felület használatával.

A C-minták létrehozása

A minta létrehozása előtt hozzá kell adnia az IoT Hub és az eszköz adatait. A klónozott IoTMQTTSample-adattárban nyissa meg a mosquitto/src/config.h fájlt. Adja hozzá az IoT Hub nevét, eszközazonosítóját és SAS-jogkivonatát az alábbiak szerint. Mindenképpen használja az IoT Hub nevét:

// 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"

Feljegyzés

Az IoTHubRootCA.crt.pem fájl tartalmazza a TLS-kapcsolat hitelesítésszolgáltatói főtanúsítványait.

Mentse a módosításokat a mosquitto/src/config.h fájlba.

A minták létrehozásához futtassa a következő parancsokat a rendszerhéjban:

cd mosquitto
cmake -Bbuild
cmake --build build

Linuxon a bináris fájlok a mosquitto mappa alatti ./build mappában találhatók.

Windows rendszerben a bináris fájlok a mosquitto mappa alatti .\build\Hibakeresés mappában találhatók.

Telemetria küldése

A mosquitto_telemetry minta bemutatja, hogyan küldhet eszközről felhőbe telemetriai üzenetet az IoT Hubra az MQTT-kódtár használatával.

A mintaalkalmazás futtatása előtt futtassa a következő parancsot az IoT Hub eseményfigyelőjének elindításához. Mindenképpen használja az IoT Hub nevét:

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

Futtassa a mosquitto_telemetry mintát. Például Linuxon:

./build/mosquitto_telemetry

A az iot hub monitor-events következő kimenetet hozza létre, amely az eszköz által küldött hasznos adatokat jeleníti meg:

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

Most már leállíthatja az eseményfigyelőt.

A kód áttekintése

A következő kódrészletek a mosquitto/src/mosquitto_telemetry.cpp fájlból származnak.

A következő utasítások határozzák meg a kapcsolati adatokat és a telemetriai üzenet küldéséhez használt MQTT-témakör nevét:

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

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

A main függvény beállítja a felhasználónevet és a jelszót az IoT Hubon való hitelesítéshez. A jelszó az eszközhöz létrehozott SAS-jogkivonat:

mosquitto_username_pw_set(mosq, USERNAME, SAS_TOKEN);

A minta az MQTT-témakör használatával küld telemetriai üzenetet az IoT Hubnak:

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");

További információ: Eszközről felhőbe irányuló üzenetek küldése.

Felhőből eszközre irányuló üzenet fogadása

A mosquitto_subscribe minta bemutatja, hogyan iratkozhat fel az MQTT-témakörökre, és hogyan fogadhat felhőből eszközre üzenetet az IoT Hubról az MQTT-kódtár használatával.

Futtassa a mosquitto_subscribe mintát. Például Linuxon:

./build/mosquitto_subscribe

Futtassa a következő parancsot egy felhőből eszközre irányuló üzenet küldéséhez az IoT Hubról. Mindenképpen használja az IoT Hub nevét:

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

A mosquitto_subscribe kimenete a következő példához hasonlóan néz ki:

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

A kód áttekintése

A következő kódrészletek a mosquitto/src/mosquitto_subscribe.cpp fájlból származnak.

Az alábbi utasítás azt a témakört határozza meg, amely szerint az eszköz a felhőből az eszköz üzeneteibe fogad. Ez # egy többszintű helyettesítő karakter:

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

A main függvény a mosquitto_message_callback_set függvény használatával állít be egy visszahívást az IoT Hubról küldött üzenetek kezelésére, és a függvény használatával feliratkozik az mosquitto_subscribe összes üzenetre. Az alábbi kódrészlet a visszahívási függvényt mutatja be:

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");
    }
}

További információ: Az MQTT használata felhőből eszközre irányuló üzenetek fogadásához.

Ikereszköz frissítése

A mosquitto_device_twin minta bemutatja, hogyan állíthat be egy jelentett tulajdonságot egy ikereszközben, majd hogyan olvashatja vissza a tulajdonságot.

Futtassa a mosquitto_device_twin mintát. Például Linuxon:

./build/mosquitto_device_twin

A mosquitto_device_twin kimenete a következő példához hasonlóan néz ki:

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.

A kód áttekintése

A következő kódrészletek a mosquitto/src/mosquitto_device_twin.cpp fájlból származnak.

Az alábbi utasítások határozzák meg azokat a témaköröket, amelyeket az eszköz az ikereszköz-frissítésekre való feliratkozáshoz, az ikereszköz olvasásához és az ikereszköz frissítéséhez használ:

#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"

A main függvény a mosquitto_connect_callback_set függvény használatával állít be egy visszahívást az IoT Hubról küldött üzenetek kezelésére, és a mosquitto_subscribe függvény használatával feliratkozik a $iothub/twin/res/# témakörre.

Az alábbi kódrészlet azt a connect_callback függvényt mutatja be, amely egy jelentett tulajdonság beállítására használja mosquitto_publish az ikereszközben. Az eszköz közzéteszi az üzenetet a $iothub/twin/PATCH/properties/reported/?$rid=%d témakörben. Az %d érték minden alkalommal növekszik, amikor az eszköz üzenetet tesz közzé a témakörben:

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

Az eszköz feliratkozik a $iothub/twin/res/# témakörre, és amikor üzenetet kap az IoT Hubtól, a message_callback függvény kezeli azt. A minta futtatásakor a message_callback függvény kétszer lesz meghívva. Az első alkalommal az eszköz választ kap az IoT Hubtól a jelentett tulajdonságfrissítésre. Az eszköz ezután kéri az ikereszközt. A második alkalommal az eszköz megkapja a kért ikereszközt. Az alábbi kódrészlet a függvényt message_callback mutatja be:

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
    }
}

További információ: Az MQTT használata az ikereszköz jelentett tulajdonságának frissítéséhez, az MQTT használata pedig egy ikereszköz-tulajdonság lekéréséhez.

Az erőforrások eltávolítása

Ha további eszközfejlesztői cikkeket tervez folytatni, megtarthatja és újra felhasználhatja a cikkben használt erőforrásokat. Ellenkező esetben törölheti a cikkben létrehozott erőforrásokat, hogy elkerülje a további díjakat.

Egyszerre törölheti a központot és a regisztrált eszközt is a teljes erőforráscsoport törlésével az alábbi Azure CLI-paranccsal. Ne használja ezt a parancsot, ha ezek az erőforrások megosztanak egy erőforráscsoportot más megtartani kívánt erőforrásokkal.

az group delete --name <YourResourceGroupName>

Ha csak az IoT Hubot szeretné törölni, futtassa a következő parancsot az Azure CLI használatával:

az iot hub delete --name <YourIoTHubName>

Ha csak az IoT Hubon regisztrált eszközidentitást szeretné törölni, futtassa a következő parancsot az Azure CLI használatával:

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

Előfordulhat, hogy a klónozott mintafájlokat is el szeretné távolítani a fejlesztőgépről.

Következő lépések

Most, hogy megtanulta, hogyan használhatja a Mosquitto MQTT-kódtárat az IoT Hubbal való kommunikációhoz, a következő javasolt lépés az alábbiak áttekintése: