Självstudie – Använda MQTT för att utveckla en IoT-enhetsklient utan att använda en enhets-SDK
Du bör använda en av SDK:erna för Azure IoT-enheter för att skapa dina IoT-enhetsklienter om det är möjligt. I scenarier som att använda en minnesbegränsad enhet kan du dock behöva använda ett MQTT-bibliotek för att kommunicera med din IoT-hubb.
Exemplen i den här självstudien använder Eclipse Mosquitto MQTT-biblioteket.
I den här självstudien lär du dig att:
- Skapa C-språkenhetens klientexempelprogram.
- Kör ett exempel som använder MQTT-biblioteket för att skicka telemetri.
- Kör ett exempel som använder MQTT-biblioteket för att bearbeta ett meddelande från molnet till enheten som skickas från din IoT-hubb.
- Kör ett exempel som använder MQTT-biblioteket för att hantera enhetstvillingen på enheten.
Du kan använda antingen en Windows- eller Linux-utvecklingsdator för att slutföra stegen i den här självstudien.
Om du inte har någon Azure-prenumeration skapar du ett kostnadsfritt konto innan du börjar.
Förutsättningar
Förbereda din miljö för Azure CLI
Använd Bash-miljön i Azure Cloud Shell. Mer information finns i Snabbstart för Bash i Azure Cloud Shell.
Om du föredrar att köra CLI-referenskommandon lokalt installerar du Azure CLI. Om du kör i Windows eller macOS kan du köra Azure CLI i en Docker-container. Mer information finns i Så här kör du Azure CLI i en Docker-container.
Om du använder en lokal installation loggar du in på Azure CLI med hjälp av kommandot az login. Slutför autentiseringsprocessen genom att följa stegen som visas i terminalen. Andra inloggningsalternativ finns i Logga in med Azure CLI.
När du uppmanas att installera Azure CLI-tillägget vid första användningen. Mer information om tillägg finns i Använda tillägg med Azure CLI.
Kör az version om du vill hitta versionen och de beroende bibliotek som är installerade. Om du vill uppgradera till den senaste versionen kör du az upgrade.
Förutsättningar för utvecklingsdator
Om du använder Windows:
Installera Visual Studio (Community, Professional eller Enterprise). Se till att aktivera skrivbordsutveckling med C++ -arbetsbelastning.
Installera CMake. Aktivera alternativet Lägg till CMake i systemsökvägen för alla användare.
Installera x64-versionen av Mosquitto.
Om du använder Linux:
Kör följande kommando för att installera byggverktygen:
sudo apt install cmake g++
Kör följande kommando för att installera Mosquitto-klientbiblioteket:
sudo apt install libmosquitto-dev
Konfigurera din miljö
Om du inte redan har en IoT-hubb kör du följande kommandon för att skapa en IoT-hubb på den kostnadsfria nivån i en resursgrupp med namnet mqtt-sample-rg
. Kommandot använder namnet my-hub
som ett exempel för namnet på IoT-hubben för att skapa. Välj ett unikt namn för din IoT-hubb som ska användas i stället my-hub
för :
az group create --name mqtt-sample-rg --location eastus
az iot hub create --name my-hub --resource-group mqtt-sample-rg --sku F1
Anteckna namnet på din IoT-hubb. Du behöver den senare.
Registrera en enhet i din IoT-hubb. Följande kommando registrerar en enhet som heter mqtt-dev-01
i en IoT-hubb med namnet my-hub
. Se till att använda namnet på din IoT-hubb:
az iot hub device-identity create --hub-name my-hub --device-id mqtt-dev-01
Använd följande kommando för att skapa en SAS-token som ger enheten åtkomst till din IoT-hubb. Se till att använda namnet på din IoT-hubb:
az iot hub generate-sas-token --device-id mqtt-dev-01 --hub-name my-hub --du 7200
Anteckna SAS-token som kommandot utdata när du behöver det senare. SAS-token ser ut som SharedAccessSignature sr=my-hub.azure-devices.net%2Fdevices%2Fmqtt-dev-01&sig=%2FnM...sNwtnnY%3D&se=1677855761
Dricks
Som standard är SAS-token giltig i 60 minuter. Alternativet --du 7200
i föregående kommando förlänger tokenvaraktigheten till två timmar. Om den upphör att gälla innan du är redo att använda den genererar du en ny. Du kan också skapa en token med en längre varaktighet. Mer information finns i az iot hub generate-sas-token.
Klona exempellagringsplatsen
Använd följande kommando för att klona exempellagringsplatsen till en lämplig plats på den lokala datorn:
git clone https://github.com/Azure-Samples/IoTMQTTSample.git
Lagringsplatsen innehåller även:
- Ett Python-exempel som använder
paho-mqtt
biblioteket. - Instruktioner för hur du använder
mosquitto_pub
CLI för att interagera med din IoT-hubb.
Skapa C-exemplen
Innan du skapar exemplet måste du lägga till IoT-hubben och enhetsinformationen. Öppna filen mosquitto/src/config.h i den klonade IoTMQTTSample-lagringsplatsen. Lägg till ditt IoT Hub-namn, enhets-ID och SAS-token på följande sätt. Se till att använda namnet på din IoT-hubb:
// 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"
Kommentar
IoTHubRootCA.crt.pem-filen innehåller CA-rotcertifikaten för TLS-anslutningen.
Spara ändringarna i filen mosquitto/src/config.h .
Skapa exemplen genom att köra följande kommandon i gränssnittet:
cd mosquitto
cmake -Bbuild
cmake --build build
I Linux finns binärfilerna i mappen ./build under mappen mosquitto .
I Windows finns binärfilerna i mappen .\build\Debug under mappen mosquitto .
Skicka telemetri
Det mosquitto_telemetry exemplet visar hur du skickar ett telemetrimeddelande från enhet till moln till din IoT-hubb med hjälp av MQTT-biblioteket.
Innan du kör exempelprogrammet kör du följande kommando för att starta händelseövervakaren för din IoT-hubb. Se till att använda namnet på din IoT-hubb:
az iot hub monitor-events --hub-name my-hub
Kör mosquitto_telemetry exempel. Till exempel i Linux:
./build/mosquitto_telemetry
az iot hub monitor-events
Genererar följande utdata som visar nyttolasten som skickas av enheten:
Starting event monitor, use ctrl-c to stop...
{
"event": {
"origin": "mqtt-dev-01",
"module": "",
"interface": "",
"component": "",
"payload": "Bonjour MQTT from Mosquitto"
}
}
Nu kan du stoppa händelseövervakaren.
Granska koden
Följande kodfragment hämtas från filen mosquitto/src/mosquitto_telemetry.cpp .
Följande instruktioner definierar anslutningsinformationen och namnet på det MQTT-ämne som du använder för att skicka telemetrimeddelandet:
#define HOST IOTHUBNAME ".azure-devices.net"
#define PORT 8883
#define USERNAME HOST "/" DEVICEID "/?api-version=2020-09-30"
#define TOPIC "devices/" DEVICEID "/messages/events/"
Funktionen main
anger användarnamnet och lösenordet för att autentisera med din IoT-hubb. Lösenordet är den SAS-token som du skapade för enheten:
mosquitto_username_pw_set(mosq, USERNAME, SAS_TOKEN);
Exemplet använder MQTT-ämnet för att skicka ett telemetrimeddelande till din IoT-hubb:
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");
Mer information finns i Skicka meddelanden från enhet till moln.
Ta emot ett meddelande från moln till enhet
Det mosquitto_subscribe exemplet visar hur du prenumererar på MQTT-ämnen och tar emot ett meddelande från molnet till enheten från din IoT-hubb med hjälp av MQTT-biblioteket.
Kör mosquitto_subscribe exempel. Till exempel i Linux:
./build/mosquitto_subscribe
Kör följande kommando för att skicka ett meddelande från molnet till enheten från din IoT-hubb. Se till att använda namnet på din IoT-hubb:
az iot device c2d-message send --hub-name my-hub --device-id mqtt-dev-01 --data "hello world"
Utdata från mosquitto_subscribe ser ut som i följande exempel:
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
Granska koden
Följande kodfragment hämtas från filen mosquitto/src/mosquitto_subscribe.cpp .
Följande instruktion definierar det ämnesfilter som enheten använder för att ta emot meddelanden från molnet till enheten. #
är ett jokertecken på flera nivåer:
#define DEVICEMESSAGE "devices/" DEVICEID "/messages/#"
Funktionen main
använder mosquitto_message_callback_set
funktionen för att ställa in ett återanrop för att hantera meddelanden som skickas från din IoT-hubb och använder mosquitto_subscribe
funktionen för att prenumerera på alla meddelanden. Följande kodfragment visar återanropsfunktionen:
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");
}
}
Mer information finns i Använda MQTT för att ta emot meddelanden från moln till enhet.
Uppdatera en enhetstvilling
Exemplet mosquitto_device_twin visar hur du anger en rapporterad egenskap i en enhetstvilling och läser sedan tillbaka egenskapen.
Kör mosquitto_device_twin exempel. Till exempel i Linux:
./build/mosquitto_device_twin
Utdata från mosquitto_device_twin ser ut som i följande exempel:
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.
Granska koden
Följande kodfragment hämtas från filen mosquitto/src/mosquitto_device_twin.cpp .
Följande instruktioner definierar de ämnen som enheten använder för att prenumerera på enhetstvillinguppdateringar, läsa enhetstvillingen och uppdatera enhetstvillingen:
#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"
Funktionen main
använder mosquitto_connect_callback_set
funktionen för att ange ett återanrop för att hantera meddelanden som skickas från din IoT-hubb och använder mosquitto_subscribe
funktionen för att prenumerera på ämnet $iothub/twin/res/#
.
Följande kodfragment visar funktionen connect_callback
som använder mosquitto_publish
för att ange en rapporterad egenskap i enhetstvillingen. Enheten publicerar meddelandet till ämnet $iothub/twin/PATCH/properties/reported/?$rid=%d
. Värdet %d
ökas varje gång enheten publicerar ett meddelande till ämnet:
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 ...
}
Enheten prenumererar på ämnet $iothub/twin/res/#
och när den tar emot ett meddelande från din IoT-hubb message_callback
hanterar funktionen det. När du kör exemplet anropas message_callback
funktionen två gånger. Första gången tar enheten emot ett svar från IoT-hubben till den rapporterade egenskapsuppdateringen. Enheten begär sedan enhetstvillingen. Den andra gången tar enheten emot den begärda enhetstvillingen. Följande kodfragment visar message_callback
funktionen:
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
}
}
Mer information finns i Använda MQTT för att uppdatera en enhetstvilling rapporterad egenskap och Använda MQTT för att hämta en enhetstvillingegenskap.
Rensa resurser
Om du planerar att fortsätta med fler artiklar för enhetsutvecklare kan du behålla och återanvända de resurser som du använde i den här artikeln. Annars kan du ta bort de resurser som du skapade i den här artikeln för att undvika fler avgifter.
Du kan ta bort både hubben och den registrerade enheten samtidigt genom att ta bort hela resursgruppen med följande Azure CLI-kommando. Använd inte det här kommandot om dessa resurser delar en resursgrupp med andra resurser som du vill behålla.
az group delete --name <YourResourceGroupName>
Om du bara vill ta bort IoT-hubben kör du följande kommando med Hjälp av Azure CLI:
az iot hub delete --name <YourIoTHubName>
Om du bara vill ta bort enhetsidentiteten som du registrerade med din IoT-hubb kör du följande kommando med Hjälp av Azure CLI:
az iot hub device-identity delete --hub-name <YourIoTHubName> --device-id <YourDeviceID>
Du kanske också vill ta bort de klonade exempelfilerna från utvecklingsdatorn.
Nästa steg
Nu när du har lärt dig hur du använder Mosquitto MQTT-biblioteket för att kommunicera med IoT Hub är ett föreslaget nästa steg att granska: