Todos los productos
Search
Centro de documentos

IoT Platform:Ejemplos

Última actualización: Sep 03, 2026

Este tema describe cómo invocar las operaciones de API del Link SDK para C con el fin de conectar dispositivos basados en Message Queuing Telemetry Transport (MQTT) 5.0 a IoT Platform y habilitar la mensajería. En este ejemplo se utiliza el archivo de código de muestra ./demos/mqtt_v5_basic_demo.c.

Contexto

Para obtener más información sobre las conexiones de dispositivos mediante MQTT 5.0, consulte Overview.

Paso 1: Inicializar el SDK

  1. Agregue los archivos de encabezado.

    #include "aiot_state_api.h"
    #include "aiot_sysdep_api.h"
    #include "aiot_mqtt_api.h"
  2. Agregue la dependencia subyacente y configure la función de salida de registros.

        aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
        aiot_state_set_logcb(demo_state_logcb);
  3. Invoque la operación aiot_mqtt_init para crear una instancia de cliente MQTT e inicializar los parámetros predeterminados.

        mqtt_handle = aiot_mqtt_init();
        if (mqtt_handle == NULL) {
            printf("aiot_mqtt_init failed\n");
            return -1;
        }

Paso 2: Configurar las funciones obligatorias

Invoque la operación aiot_mqtt_setopt para configurar los siguientes elementos. Para obtener más información sobre los parámetros de la operación, consulte aiot_mqtt_option_t.

  1. Configure los parámetros de conexión.

    • Código de muestra:

       char *product_key = "a18wP******";
       char *device_name = "LightSwitch";
       char *device_secret = "uwMTmVAMnGGHaAkqmeDY6cHxxB******";
       char *mqtt_host = "iot-06z00ax1o******.mqtt.iothub.aliyuncs.com";
       ...
       ...
       /* Specify the version of MQTT. */
       protocol_version = AIOT_MQTT_VERSION_5_0;
       aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_VERSION, (void *)&protocol_version);
       /* Specify the endpoint of the MQTT broker.  */
       aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_HOST, (void *)url);
       /* Specify the port of the MQTT broker.  */
       aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PORT, (void *)&port);
       /* Specify the ProductKey of the product to which the device belongs.  */
       aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PRODUCT_KEY, (void *)product_key);
       /* Specify the DeviceName of the device.  */
       aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_NAME, (void *)device_name);
       /* Specify the DeviceSecret of the device.  */
       aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_SECRET, (void *)device_secret);
       /* Specify the security credential of the connection.  */
       aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_NETWORK_CRED, (void *)&cred);
       /* If you want to use the Assigned Client Identifier feature of MQTT 5.0, set the use_assigned_clientid parameter to 1.*/
       uint8_t use_assigned_clientid = 0;
       aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_ASSIGNED_CLIENTID, (void *)(&use_assigned_clientid));
    • Parámetros:

      Parámetro

      Ejemplo

      Descripción

      mqtt_host

      iot-06z00ax1o******.mqtt.iothub.aliyuncs.com

      El endpoint al que desea conectar el dispositivo.

      • Para consultar el endpoint de una instancia Enterprise Edition o de una instancia pública de la nueva versión, vaya al panel Development Configurations de la página Instance Details en la consola de IoT Platform.

      • Si utiliza una instancia pública de la versión anterior, el endpoint de la instancia pública tiene el formato ${YourProductKey}.iot-as-mqtt.${YourRegionId}.aliyuncs.com.

      Para obtener más información sobre las instancias públicas de la nueva y la antigua versión, las instancias Enterprise Edition y los endpoints, consulte View the endpoint of an instance.

      product_key

      a18wP******

      La información de verificación del dispositivo. Para obtener más información, consulte Obtain device verification information.

      En este ejemplo se utiliza el método de verificación de certificado único por dispositivo.

      device_name

      LightSwitch

      device_secret

      uwMTmVAMnGGHaAkqmeDY6cHxxB******

      protocol_version

      AIOT_MQTT_VERSION_5_0

      Especifique 5.0 como número de versión de MQTT.

      use_assigned_clientid

      1

      Si desea utilizar la función Assigned Client Identifier de MQTT 5.0, establezca el parámetro use_assigned_clientid en 1.

    • Descripción del mecanismo keep-alive de MQTT:

      Importante
      • Durante un periodo de keep-alive, el dispositivo debe enviar como mínimo un mensaje, incluidas las solicitudes de ping.

      • Un temporizador se inicia cuando IoT Platform envía un mensaje CONNACK como respuesta a un mensaje CONNECT. Si IoT Platform recibe un mensaje PUBLISH, SUBSCRIBE, PING o PUBACK, el temporizador se restablece. IoT Platform comprueba el latido de la conexión MQTT cada 30 segundos. El tiempo de espera para la comprobación del latido es el periodo transcurrido entre el momento en que un dispositivo se conecta a IoT Platform y el momento en que se realiza la siguiente comprobación de latido. El tiempo máximo de espera se calcula mediante la siguiente fórmula: Intervalo de latido × 1.5 + Tiempo de espera para la comprobación de latido. Si el servidor no recibe mensajes del dispositivo dentro del tiempo máximo de espera, finaliza la conexión con el dispositivo.

      Link SDK para C proporciona el mecanismo keep-alive. La siguiente tabla describe el parámetro que puede configurar para especificar valores personalizados relacionados con el latido para las conexiones de dispositivos. De lo contrario, se utilizan los valores predeterminados.

      Elemento

      Valor predeterminado

      Descripción

      AIOT_MQTTOPT_HEARTBEAT_MAX_LOST

      2

      El número máximo de latidos que pueden perderse. Si se supera el límite, el sistema establece una nueva conexión.

      AIOT_MQTTOPT_HEARTBEAT_INTERVAL_MS

      25,000

      El intervalo entre una desconexión y una nueva conexión establecida por el sistema. Valores válidos: de 1000 a 1200000. Unidad: milisegundos.

      AIOT_MQTTOPT_KEEPALIVE_SEC

      1,200

      El periodo de keep-alive. Después de perderse el latido, el sistema puede establecer una nueva conexión dentro de un periodo especificado. Valor válido: de 30 a 1200. Unidad: segundos. Se recomienda especificar un valor mayor que 300.

  2. Configure las devoluciones de llamada para supervisar el estado y recibir mensajes.

    1. Configure una devolución de llamada para supervisar el estado.

      • Código de muestra:

         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);
         ...
         ...
        }
         
      • Parámetros:

        Elemento

        Ejemplo

        Descripción

        AIOT_MQTTOPT_RECV_HANDLER

        demo_mqtt_default_recv_handler

        Cuando se recibe un mensaje, se invoca la devolución de llamada para realizar las operaciones necesarias.

        AIOT_MQTTOPT_EVENT_HANDLER

        demo_mqtt_event_handler

        Cuando cambia el estado de la conexión del dispositivo, se invoca la devolución de llamada para realizar las operaciones necesarias.

    2. Defina la devolución de llamada para supervisar el estado.

      Importante
      • No especifique lógica que consuma mucho tiempo para gestionar eventos. De lo contrario, los hilos utilizados para recibir paquetes podrían bloquearse.

      • El estado de la conexión cambia debido a varias causas, como excepciones de red, reconexiones automáticas y desconexiones.

      • Para gestionar los cambios en el estado de la conexión, puede modificar el código en la sección TODO según sus requisitos empresariales.

      /* 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 to the MQTT broker.  */
       case AIOT_MQTTEVT_CONNECT: {
       printf("AIOT_MQTTEVT_CONNECT\n");
       /* TODO: Specify the logic to establish a connection. 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 to the MQTT broker.  */
       case AIOT_MQTTEVT_RECONNECT: {
       printf("AIOT_MQTTEVT_RECONNECT\n");
       /* TODO: Specify the logic to re-establish a connection. 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: {
      
       }
       }
      }
       
    3. Defina la devolución de llamada para recibir mensajes.

      Importante
      • No especifique lógica que consuma mucho tiempo para procesar mensajes. De lo contrario, los hilos utilizados para recibir paquetes podrían bloquearse.

      • Para procesar los mensajes recibidos, puede modificar el código en la sección TODO según sus requisitos empresariales.

      /* The default callback function that can be called to receive MQTT messages. This function is called when the SDK receives an MQTT message from the MQTT broker and no custom callback is available. */
      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: Define the logic for sending a heartbeat response to the server. In most cases, a response is not sent. */
              }
              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: Define the logic for sending a response from the MQTT broker to a subscription request. In most cases, a response is not sent. */
              }
              break;
              case AIOT_MQTTRECV_UNSUB_ACK: {
                  printf("unsuback, , packet id: %d\n",
                         packet->data.unsub_ack.packet_id);
                  /* TODO: Define the logic for sending a response from the MQTT broker to a subscription request. In most cases, a response is not sent. */
              }
              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);
                  printf("pub, payload len: %x\n", packet->data.pub.payload_len);
                  aiot_mqtt_props_print(packet->data.pub.props);
              }
              break;
      
              case AIOT_MQTTRECV_PUB_ACK: {
                  printf("puback, packet id: %d\n", packet->data.pub_ack.packet_id);
                  /* TODO: Define the logic for sending a response from the MQTT broker to a reported QoS 1 message. Typically, a response is not sent. */
              }
              break;
      
              case AIOT_MQTTRECV_CON_ACK: {
                  aiot_mqtt_props_print(packet->data.con_ack.props);
              }
              break;
              case AIOT_MQTTRECV_DISCONNECT: {
                  printf("server disconnect, reason code: 0x%x\n", packet->data.server_disconnect.reason_code);
              }
              break;
       
              default: {
      
              }
          }
      }
    4. Paso 3: Establecer una conexión

      Invoque la operación aiot_mqtt_connect_v5 para enviar una solicitud de conexión y autenticación a IoT Platform. Para obtener información sobre cómo configurar los parámetros, consulte Configurar parámetros de conexión.

      Nota

      Para obtener más información sobre la propiedad de usuario MQTT_PROP_ID_USER_PROPERTY que se especifica en el siguiente código de muestra, consulte mqtt_property_identify_t.

      mqtt_properties_t *conn_props = aiot_mqtt_props_init();
      mqtt_property_t user_prop = {
          .id = MQTT_PROP_ID_USER_PROPERTY,
          .value.str_pair.key.len = strlen("demo_key"),
          .value.str_pair.key.value = (uint8_t *)"demo_key",
          .value.str_pair.value.len = strlen("demo_value"),
          .value.str_pair.value.value = (uint8_t *)"demo_value",
      };
      aiot_mqtt_props_add(conn_props, &user_prop);
      /* Establish a connection to the server over MQTT 5.0. */
      res = aiot_mqtt_connect_v5(mqtt_handle, NULL, conn_props);
      aiot_mqtt_props_deinit(&conn_props);
      if (res < STATE_SUCCESS) {
          /* If the MQTT connection fails to be established, release the resources of the MQTT instance. */
          aiot_mqtt_deinit(&mqtt_handle);
          printf("aiot_mqtt_connect failed: -0x%04X\n\r\n", -res);
          printf("please check variables like mqtt_host, produt_key, device_name, device_secret in demo\r\n");
          return -1;
      }

      Paso 4: Habilitar hilos de keep-alive

      Invoque la operación aiot_mqtt_process para enviar un mensaje de latido al agente MQTT y reenviar los mensajes QoS 1 para los que no se generaron respuestas. De esta manera se habilita una conexión persistente.

      1. Habilite los hilos 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;
            }
      2. Para gestionar los hilos de keep-alive, defina la siguiente función:

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

      Paso 5: Habilitar hilos para recibir mensajes

      Invoque la operación aiot_mqtt_recv para recibir mensajes MQTT del agente. Las operaciones necesarias se realizan mediante la devolución de llamada para recibir mensajes. Si ocurre una desconexión y posteriormente una reconexión automática, las operaciones necesarias se realizan mediante la devolución de llamada para gestionar eventos.

      1. Habilite los hilos para recibir mensajes.

            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;
            }
                                            
      2. Para gestionar los hilos, defina la siguiente función:

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

      Paso 6: Suscribirse a un tema

      Invoque la operación aiot_mqtt_sub_v5 para suscribirse a un tema específico.

      • Código de muestra:

            /* Use the sample code that shows how to subscribe to a topic over MQTT based on your business requirements. */
            {
                char *sub_topic = "/sys/${YourProductKey}/${YourDeviceName}/thing/event/property/post_reply";
                mqtt_properties_t *sub_props = aiot_mqtt_props_init();
                aiot_mqtt_props_add(sub_props, &user_prop);
                /* The subscription options. */
                sub_options_t opts = {
                    .no_local = 1,
                    .qos = 1,
                    .retain_as_publish = 1,
                    .retain_handling = 1,
                };
                res = aiot_mqtt_sub_v5(mqtt_handle, sub_topic, &opts, NULL, NULL, sub_props);
                aiot_mqtt_props_deinit(&sub_props);
                if (res < 0) {
                    printf("aiot_mqtt_sub failed, res: -0x%04X\n", -res);
                    aiot_mqtt_deinit(&mqtt_handle);
                    return -1;
                }
            }
        Nota
        • Para obtener más información sobre la propiedad de usuario MQTT_PROP_ID_USER_PROPERTY que se especifica en el siguiente código, consulte mqtt_property_identify_t.

        • Para obtener más información sobre cómo especificar opciones de suscripción, consulte sub_options_t.

      • Parámetros:

        Parámetro

        Ejemplo

        Descripción

        sub_topic

        /a18wP******/LightSwitch/user/get

        El tema sobre el cual el dispositivo tiene permiso de suscripción. Descripción:

        • a1oGs****** es la ProductKey del dispositivo.

        • LightSwitch es el DeviceName del dispositivo.

        En este ejemplo se utiliza el tema personalizado predeterminado.

        El dispositivo puede recibir mensajes de IoT Platform mediante este tema.

        Para obtener más información, consulte What is a topic.

        sub_props

        aiot_mqtt_props_init()

        Las propiedades adicionales que desea especificar para la suscripción.

        opts

        .no_local = 1,

        .qos = 1,

        .retain_as_publish = 1,

        .retain_handling = 1,

        Las opciones de suscripción.

      Paso 7: Enviar un mensaje

      Invoque la operación aiot_mqtt_pub_v5 para enviar un mensaje a un tema específico.

      • Código de muestra:

        	mqtt_properties_t *pub_props = aiot_mqtt_props_init();
          /* Use the sample code that shows how to send a message over MQTT based on your business requirements.*/
          char *pub_topic = "/sys/${YourProductKey}/${YourDeviceName}/thing/event/property/post";
          char *pub_payload = "{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}";
          mqtt_property_t response_prop = {
              .id = MQTT_PROP_ID_RESPONSE_TOPIC,
              .value.str.len = strlen(pub_topic),
              .value.str.value = (uint8_t *)pub_topic,
           };
           char *demo_data_str = "12345";
           mqtt_property_t correlation_prop = {
               .id = MQTT_PROP_ID_CORRELATION_DATA,
               .value.str.len = strlen(demo_data_str),
               .value.str.value = (uint8_t *)demo_data_str,
           };
           aiot_mqtt_props_add(pub_props, &response_prop);
           aiot_mqtt_props_add(pub_props, &correlation_prop);
           res = aiot_mqtt_pub_v5(mqtt_handle, pub_topic, (uint8_t *)pub_payload, (uint32_t)(strlen(pub_payload)), 1,0, pub_props);
           if (res < 0) {
               printf("aiot_mqtt pub failed, res: -0x%04X\n", -res);
               aiot_mqtt_deinit(&mqtt_handle);
               return -1;
           }
        Nota

        Para obtener más información sobre la propiedad de usuario MQTT_PROP_ID_USER_PROPERTY que se especifica en el siguiente código, consulte mqtt_property_identify_t.

      • Parámetros:

        Parámetro

        Ejemplo

        Descripción

        pub_topic

        /a18wP******/LightSwitch/user/update

        El tema sobre el cual tiene permiso de publicación. Descripción:

        • a1oGs****** indica la ProductKey del dispositivo.

        • LightSwitch indica el DeviceName del dispositivo.

        El dispositivo envía mensajes a IoT Platform mediante este tema.

        Para obtener más información, consulte What is a topic.

        pub_payload

        {\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}

        El contenido del mensaje que desea enviar a IoT Platform.

        En este ejemplo se utiliza un tema personalizado. Por lo tanto, puede especificar un formato de mensaje personalizado.

        Para obtener más información, consulte Data formats.

        pub_props

        Para obtener más información, consulte el código de muestra.

        Las propiedades que se incluyen en el mensaje.

      Una vez establecida la conexión MQTT entre el dispositivo e IoT Platform, asegúrese de que el número de mensajes no supere el umbral.

      • Para obtener más información sobre los límites de comunicación, consulte Limits.

      • Si el número de mensajes supera el umbral, inicie sesión en la consola de IoT Platform para consultar los mensajes acumulados. Para obtener más información, consulte View and monitor consumer groups.

      Paso 8: Desconectar el dispositivo de IoT Platform

      Invoque la operación aiot_mqtt_disconnect_v5 para desconectar el dispositivo de IoT Platform.

      Para obtener más información sobre la propiedad de usuario MQTT_PROP_ID_USER_PROPERTY que se especifica en el siguiente código de muestra, consulte mqtt_property_identify_t.

      Nota

      Las conexiones MQTT están diseñadas para dispositivos que permanecen conectados de forma persistente. Puede desconectar dispositivos de IoT Platform. En este ejemplo, el hilo principal se utiliza para configurar parámetros y establecer una conexión. Una vez establecida la conexión, puede poner el hilo principal en reposo.

          {
              mqtt_properties_t *disconn_props = aiot_mqtt_props_init();
              /* The reason code 0x0 indicates a normal disconnection. */
              int demo_reason_code = 0x0;
              char *demo_reason_string = "normal_exit";
              mqtt_property_t reason_prop = {.id = MQTT_PROP_ID_REASON_STRING, .value.str.len = strlen(demo_reason_string), .value.str.value = (uint8_t *)demo_reason_string};
              aiot_mqtt_props_add(disconn_props, &reason_prop);
              res = aiot_mqtt_disconnect_v5(mqtt_handle, demo_reason_code, disconn_props);
              aiot_mqtt_props_deinit(&disconn_props);
          }

      Paso 9: Salir del programa

      Invoque la operación aiot_mqtt_deinit para eliminar la instancia de cliente MQTT y liberar los recursos correspondientes.

       res = aiot_mqtt_deinit(&mqtt_handle);
       if (res < STATE_SUCCESS) {
       printf("aiot_mqtt_deinit failed: -0x%04X\n", -res);
       return -1;
       }

      Siguientes pasos

      • Después de configurar el archivo de código de muestra, compílelo para generar un archivo ejecutable. En este ejemplo se genera el archivo ejecutable ./output/mqtt-v5-basic-demo.

        Para obtener más información, consulte Prepare an environment.

      • Para obtener más información sobre el resultado de la ejecución, consulte Operational logs.