Cette rubrique explique comment appeler les opérations d'API du SDK Link pour C afin de connecter des appareils basés sur MQTT à IoT Platform et de recevoir des messages. Cet exemple utilise le fichier de code exemple ./mqtt_basic_demo.c.
Contexte
Pour plus d'informations sur les connexions MQTT, consultez la section Vue d'ensemble.
Étape 1 : Initialiser un client
-
Ajoutez les fichiers d'en-tête.
#include "aiot_state_api.h" #include "aiot_sysdep_api.h" #include "aiot_mqtt_api.h" -
Ajoutez la dépendance sous-jacente et configurez la fonctionnalité de sortie des journaux.
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile); aiot_state_set_logcb(demo_state_logcb); -
Appelez l'opération aiot_mqtt_init pour créer une instance de client MQTT et initialiser les paramètres par défaut.
mqtt_handle = aiot_mqtt_init(); if (mqtt_handle == NULL) { printf("aiot_mqtt_init failed\n"); return -1; }
Étape 2 : Configurer les fonctionnalités requises
Appelez l'opération aiot_mqtt_setopt pour configurer les éléments suivants :
Pour plus d'informations sur les paramètres de l'opération, consultez la documentation relative à aiot_mqtt_option_t.
-
Définissez les paramètres de connexion.
-
Exemple de code
char *product_key = "a18wP******"; char *device_name = "LightSwitch"; char *device_secret = "uwMTmVAMnGGHaAkqmeDY6cHxxB******"; char *mqtt_host = "iot-06z00ax1o******.mqtt.iothub.aliyuncs.com"; ... ... /* Set the endpoint of the MQTT broker. */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_HOST, (void *)url); /* Set the port of the MQTT broker. */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PORT, (void *)&port); /* Set the ProductKey of the device. */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PRODUCT_KEY, (void *)product_key); /* Set the DeviceName of the device. */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_NAME, (void *)device_name); /* Set the DeviceSecret of the device. */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_SECRET, (void *)device_secret); /* Set the security credential of the connection. */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_NETWORK_CRED, (void *)&cred); -
Paramètres :
Parameter
Example
Description
mqtt_host
iot-06z00ax1o.mqtt.iothub.aliyuncs.com
L'endpoint.
Si vous utilisez une instance Enterprise Edition ou une instance publique activée le 30 juillet 2021 ou après cette date, consultez l'endpoint sur la page Instance Details . Cliquez sur View Development Configurations dans le coin supérieur droit. L'endpoint s'affiche dans le panneau Development Configurations.
Si vous utilisez une instance publique activée avant le 30 juillet 2021, l'endpoint est
${YourProductKey}.iot-as-mqtt.${YourRegionId}.aliyuncs.com.
product_key
a18wP
Les informations d'authentification de l'appareil. Pour plus d'informations, consultez la section Obtenir les informations d'authentification de l'appareil.
Dans cet exemple, la méthode d'authentification unique-certificate-per-device est utilisée.
device_name
LightSwitch
device_secret
uwMTmVAMnGGHaAkqmeDY6cHxxB
-
Description du maintien de la connexion MQTT (keep-alive) :
ImportantPendant la période de keep-alive, l'appareil doit envoyer au moins un message, y compris des requêtes ping.
Un minuteur démarre lorsque IoT Platform envoie un message CONNACK en réponse à un message CONNECT. Lorsqu'IoT Platform reçoit un message PUBLISH, SUBSCRIBE, PING ou PUBACK, le minuteur est réinitialisé. IoT Platform vérifie le signal de maintien de la connexion (heartbeat) de la connexion MQTT toutes les 30 secondes. Le temps d'attente pour la vérification du heartbeat correspond à la période entre le moment où un appareil se connecte à IoT Platform et le moment où la prochaine vérification du heartbeat est effectuée. La durée maximale de délai d'expiration est calculée à l'aide de la formule suivante :
Heartbeat interval × 1.5 + Wait time for the heartbeat check. Si le serveur ne reçoit aucun message de l'appareil dans le délai maximal d'expiration, il met fin à la connexion avec l'appareil.
Le SDK Link pour C fournit la fonctionnalité de keep-alive. Vous pouvez spécifier les paramètres suivants pour personnaliser le heartbeat d'une connexion. Sinon, les valeurs par défaut sont utilisées.
|
**Parameter**
|
**Default value**
|
**Description**
| | --- | --- | --- | |
AIOT_MQTTOPT_HEARTBEAT_MAX_LOST
|
2
|
Le nombre maximal de heartbeats pouvant être perdus. Si la limite est dépassée, une reconnexion est établie.
| |
AIOT_MQTTOPT_HEARTBEAT_INTERVAL_MS
|
25,000
|
L'intervalle entre les heartbeats. Unité : millisecondes. Valeurs valides : 1 000 à 1 200 000.
| |
AIOT_MQTTOPT_KEEPALIVE_SEC
|
1,200
|
La durée du keep-alive. Après la perte du heartbeat, vous pouvez rétablir une connexion dans le délai spécifié. Valeurs valides : 30 à 1 200. Unité : secondes. Nous vous recommandons de définir une valeur supérieure à 300.
|
-
-
Configurez les rappels pour surveiller l'état et recevoir des messages.
-
Spécifiez les rappels pour surveiller l'état.
-
Exemple de code
int main(int argc, char *argv[]) { ... ... /* Specify the default callback to receive MQTT messages. */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_RECV_HANDLER, (void *)demo_mqtt_default_recv_handler); /* Specify the callback to handle MQTT events. */ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_EVENT_HANDLER, (void *)demo_mqtt_event_handler); ... ... } -
Paramètres :
|
**Parameter**
|
**Example**
|
**Description**
| | --- | --- | --- | |
AIOT_MQTTOPT_RECV_HANDLER
|
demo_mqtt_default_recv_handler
|
Lorsqu'un message est reçu, le rappel est appelé pour effectuer les opérations requises.
| |
AIOT_MQTTOPT_EVENT_HANDLER
|
demo_mqtt_event_handler
|
Lorsque l'état de la connexion de l'appareil change, le rappel est appelé pour effectuer les opérations requises.
|
-
-
Définissez le rappel pour surveiller l'état.
ImportantÉvitez d'inclure une logique gourmande en ressources dans la gestion des événements. Cela pourrait bloquer les threads utilisés pour recevoir les paquets.
Les changements d'état de connexion incluent les exceptions réseau, les reconnexions automatiques et les déconnexions.
Pour gérer les changements d'état de connexion, vous pouvez modifier le code selon vos besoins dans la section
TODO.
/* The callback to handle MQTT events. When the connection is created, recovered, or closed, the callback is called. For information about the event definition, see core/aiot_mqtt_api.h. */ void demo_mqtt_event_handler(void *handle, const aiot_mqtt_event_t *event, void *userdata) { switch (event->type) { /* Call the aiot_mqtt_connect operation to establish a connection with the MQTT broker. */ case AIOT_MQTTEVT_CONNECT: { printf("AIOT_MQTTEVT_CONNECT\n"); /* TODO: Specify the processing logic after the connection is established. Do not call time-consuming functions that may block threads. */ } break; /* If a disconnection error occurs due to a network exception, the SDK automatically initiates a request to reconnect with the MQTT broker. */ case AIOT_MQTTEVT_RECONNECT: { printf("AIOT_MQTTEVT_RECONNECT\n"); /* TODO: Specify the processing logic after the connection is re-established. Do not call time-consuming functions that may block threads. */ } break; /* A disconnection error occurs due to a network exception. The underlying read or write operation fails. A heartbeat response is not obtained from the MQTT broker. */ case AIOT_MQTTEVT_DISCONNECT: { char *cause = (event->data.disconnect == AIOT_MQTTDISCONNEVT_NETWORK_DISCONNECT) ? ("network disconnect") : ("heartbeat disconnect"); printf("AIOT_MQTTEVT_DISCONNECT: %s\n", cause); /* TODO: Specify the logic to process disconnection issues. Do not call time-consuming functions that may block threads. */ } break; default: { } } } -
Définissez le rappel pour recevoir des messages.
ImportantÉvitez d'inclure une logique gourmande en ressources dans le traitement des messages. Cela pourrait bloquer les threads utilisés pour recevoir les paquets.
Pour traiter les messages reçus, vous pouvez modifier le code selon vos besoins dans la section
TODO.
/* The default callback to process MQTT messages. When the SDK receives messages from the MQTT broker and you do not configure callbacks, the following operation is called. */ void demo_mqtt_default_recv_handler(void *handle, const aiot_mqtt_recv_t *packet, void *userdata) { switch (packet->type) { case AIOT_MQTTRECV_HEARTBEAT_RESPONSE: { printf("heartbeat response\n"); /* TODO: Specify the logic to process heartbeat responses from the MQTT broker. In most cases, this logic is not required. */ } break; case AIOT_MQTTRECV_SUB_ACK: { printf("suback, res: -0x%04X, packet id: %d, max qos: %d\n", -packet->data.sub_ack.res, packet->data.sub_ack.packet_id, packet->data.sub_ack.max_qos); /* TODO: Specify the logic to process the responses of the MQTT broker to subscription requests. In most cases, this logic is not required. */ } break; case AIOT_MQTTRECV_PUB: { printf("pub, qos: %d, topic: %.*s\n", packet->data.pub.qos, packet->data.pub.topic_len, packet->data.pub.topic); printf("pub, payload: %.*s\n", packet->data.pub.payload_len, packet->data.pub.payload); /* TODO: Specify the logic to process the messages that are sent from the MQTT broker. */ } break; case AIOT_MQTTRECV_PUB_ACK: { printf("puback, packet id: %d\n", packet->data.pub_ack.packet_id); /* TODO: Specify the logic to process the responses of the MQTT broker to QoS 1 messages. In most cases, this logic is not required. */ } break; default: { } } }
-
Étape 3 : Établir une connexion
Appelez l'opération aiot_mqtt_connect pour envoyer une demande de connexion et d'authentification à IoT Platform. Pour savoir comment spécifier les paramètres, consultez la section Définir les paramètres de connexion.
/* Establish an MQTT connection with IoT Platform. */
res = aiot_mqtt_connect(mqtt_handle);
if (res < STATE_SUCCESS) {
/* Release resources of the MQTT instance if the MQTT connection fails to be established. */
aiot_mqtt_deinit(&mqtt_handle);
printf("aiot_mqtt_connect failed: -0x%04X\n", -res);
return -1;
}
Étape 4 : Activer le thread de keep-alive
Appelez l'opération aiot_mqtt_process pour envoyer un message heartbeat au courtier MQTT et renvoyer les messages QoS 1 pour lesquels aucune réponse n'a été générée. Cela permet de maintenir une connexion persistante.
-
Activez le thread de keep-alive.
res = pthread_create(&g_mqtt_process_thread, NULL, demo_mqtt_process_thread, mqtt_handle); if (res < 0) { printf("pthread_create demo_mqtt_process_thread failed: %d\n", res); return -1; } -
Configurez la fonction pour gérer le thread de keep-alive.
void *demo_mqtt_process_thread(void *args) { int32_t res = STATE_SUCCESS; while (g_mqtt_process_thread_running) { res = aiot_mqtt_process(args); if (res == STATE_USER_INPUT_EXEC_DISABLED) { break; } sleep(1); } return NULL; }
Étape 5 : Activer le thread de réception des messages
Appelez l'opération aiot_mqtt_recv pour recevoir les messages MQTT du courtier. Les opérations requises sont effectuées à l'aide du rappel de réception des messages. En cas de déconnexion suivie d'une reconnexion automatique, les opérations requises sont effectuées à l'aide du rappel de gestion des événements.
-
Activez le thread de réception des messages.
res = pthread_create(&g_mqtt_recv_thread, NULL, demo_mqtt_recv_thread, mqtt_handle); if (res < 0) { printf("pthread_create demo_mqtt_recv_thread failed: %d\n", res); return -1; } -
Configurez la fonction pour gérer le thread.
void *demo_mqtt_recv_thread(void *args) { int32_t res = STATE_SUCCESS; while (g_mqtt_recv_thread_running) { res = aiot_mqtt_recv(args); if (res < STATE_SUCCESS) { if (res == STATE_USER_INPUT_EXEC_DISABLED) { break; } sleep(1); } } return NULL; }
Étape 6 : S'abonner à un sujet
Appelez l'opération aiot_mqtt_sub pour vous abonner à un sujet spécifié.
-
Exemple de code
{ char *sub_topic = "/a18wP******/LightSwitch/user/get"; res = aiot_mqtt_sub(mqtt_handle, sub_topic, NULL, 1, NULL); if (res < 0) { printf("aiot_mqtt_sub failed, res: -0x%04X\n", -res); return -1; } }RemarqueAprès avoir configuré l'exemple de code, supprimez les symboles de commentaire de part et d'autre du code.
-
Paramètres :
Parameter
Example
Description
sub_topic
/a18wP/LightSwitch/user/get
Le sujet disposant de l'autorisation Subscribe.
a18wPindique le ProductKey de l'appareil.LightSwitchindique le DeviceName de l'appareil.
Dans cet exemple, le sujet personnalisé par défaut est utilisé.
L'appareil peut recevoir des messages d'IoT Platform via ce sujet.
Pour plus d'informations sur les sujets, consultez la section Sujets.
Étape 7 : Envoyer un message
Appelez l'opération aiot_mqtt_pub pour envoyer un message à un sujet spécifié.
-
Exemple de code
{ char *pub_topic = "/a18wP******/LightSwitch/user/update"; char *pub_payload = "{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}"; res = aiot_mqtt_pub(mqtt_handle, pub_topic, (uint8_t *)pub_payload, (uint32_t)strlen(pub_payload), 0); if (res < 0) { printf("aiot_mqtt_sub failed, res: -0x%04X\n", -res); return -1; } }RemarqueAprès avoir configuré l'exemple de code, supprimez les symboles de commentaire de part et d'autre du code.
-
Paramètres :
Parameter
Example
Description
pub_topic
/a18wP/LightSwitch/user/update
Le sujet disposant de l'autorisation Publish.
a18wPindique le ProductKey de l'appareil.LightSwitchindique le DeviceName de l'appareil.
L'appareil peut envoyer des messages à IoT Platform via ce sujet.
Pour plus d'informations sur les sujets, consultez la section Sujets.
pub_payload
{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}
Le message envoyé à IoT Platform.
Dans cet exemple, un sujet personnalisé est utilisé. Par conséquent, vous pouvez personnaliser le format du message.
Pour plus d'informations sur les formats de message, consultez la section Formats de données.
Une fois la connexion MQTT entre l'appareil et IoT Platform établie, assurez-vous que le nombre de messages ne dépasse pas le seuil.
Pour plus d'informations sur les limites, consultez la rubrique Limits de la documentation IoT Platform relative aux Connexions et communications.
Si le nombre de messages dépasse le seuil, connectez-vous à la console IoT Platform pour afficher les messages accumulés. Pour plus d'informations, consultez la section Afficher et surveiller les groupes de consommateurs.
Étape 8 : Déconnecter l'appareil d'IoT Platform
Les connexions MQTT s'appliquent aux appareils qui restent connectés en permanence. Vous pouvez déconnecter manuellement les appareils d'IoT Platform.
Dans cet exemple, le thread principal est utilisé pour définir les paramètres et établir la connexion. Une fois la connexion établie, vous pouvez mettre le thread principal en veille.
Appelez l'opération aiot_mqtt_disconnect pour déconnecter l'appareil d'IoT Platform.
res = aiot_mqtt_disconnect(mqtt_handle);
if (res < STATE_SUCCESS) {
aiot_mqtt_deinit(&mqtt_handle);
printf("aiot_mqtt_disconnect failed: -0x%04X\n", -res);
return -1;
}
Étape 9 : Quitter le programme
Appelez l'opération aiot_mqtt_deinit pour détruire l'instance du client MQTT et libérer les ressources.
res = aiot_mqtt_deinit(&mqtt_handle);
if (res < STATE_SUCCESS) {
printf("aiot_mqtt_deinit failed: -0x%04X\n", -res);
return -1;
}
Étapes suivantes
-
Après avoir configuré le fichier de code exemple, compilez-le pour générer un fichier exécutable. Dans cet exemple, le fichier exécutable
./output/mqtt-basic-demoest généré.Pour plus d'informations, consultez la section Compilation et exécution.
Pour plus d'informations sur les résultats d'exécution, consultez la section Afficher les journaux.