すべてのプロダクト
Search
ドキュメントセンター

IoT Platform:例

最終更新日:Apr 09, 2025

このトピックでは、Link SDK for CのAPI操作を呼び出して、Message Queuing Telemetry Transport (MQTT) 5.0ベースのデバイスをIoT Platformに接続し、メッセージングを有効にする方法について説明します。 この例では、。/demos/mqtt_v5_basic_demo.cサンプルコードファイルを使用します。

背景情報

MQTT 5.0を介したデバイス接続の詳細については、「概要」をご参照ください。

手順1: SDKの初期化

  1. ヘッダーファイルを追加します。

    # 「aiot_state_api.h」を含める
    # 「aiot_sysdep_api.h」を含む
    # 「aiot_mqtt_api.h」
    を含む
  2. 基になる依存関係を追加し、ログ出力機能を設定します。

    aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
        aiot_state_set_logcb(demo_state_logcb); 
  3. aiot_mqtt_init操作を呼び出してMQTTクライアントインスタンスを作成し、デフォルトパラメーターを初期化します。

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

ステップ2: 必要な機能の設定

aiot_mqtt_setopt操作を呼び出して、次の項目を設定します。操作のパラメーターの詳細については、「aiot_mqtt_option_t」をご参照ください。

  1. 接続パラメータを設定します。

    • サンプルコード:

      char * product_key = "a18wP ******";
       char * device_name = "LightSwitch";
       char * device_secret = "uwMTmVAMnGGHaAkqmeDY6cHxxB ******";
       char * mqtt_host = "iot-06z00ax1o ****** .mqtt.iothub.aliyuncs.com";
       ...
       ...
       /* MQTTのバージョンを指定します。 */
       protocol_version = AIOT_MQTT_VERSION_5_0;
       aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_VERSION, (void *)&protocol_version);
       /* MQTTブローカーのエンドポイントを指定します。  */
       aiot_mqtt_setopt(mqtt_handle、AIOT_MQTTOPT_HOST、(void *)url);
       /* MQTTブローカーのポートを指定します。  */
       aiot_mqtt_setopt(mqtt_handle、AIOT_MQTTOPT_PORT、(void *)&port);
       /* デバイスが属するプロダクトのProductKeyを指定します。  */
       aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PRODUCT_KEY, (void *)product_key);
       /* デバイスのDeviceNameを指定します。  */
       aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_NAME, (void *)device_name);
       /* デバイスのDeviceSecretを指定します。  */
       aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_SECRET, (void *)device_secret);
       /* 接続のセキュリティ資格情報を指定します。  */
       aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_NETWORK_CRED, (void *)&cred);
       /* MQTT 5.0のAssigned Client Identifier機能を使用する場合は、use_assigned_clientidパラメーターを1に設定します。* /
       uint8_t use_assigned_clientid = 0;
       aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_ASSIGNED_CLIENTID, (void *)(&use_assigned_clientid)); 
    • パラメーター:

      パラメーター

      説明

      mqtt_host

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

      デバイスを接続するエンドポイント。

      • Enterprise Editionインスタンスまたは新しいバージョンのパブリックインスタンスのエンドポイントを表示するには、IoT Platformコンソールの [インスタンスの詳細] ページの [開発設定] パネルに移動します。

      • 以前のバージョンのパブリックインスタンスを使用している場合、パブリックインスタンスのエンドポイントは ${YourProductKey} .iot-as-mqttにあります。${YourRegionId} です。aliyuncs.com形式。

      新バージョンと旧バージョンのパブリックインスタンス、Enterprise Editionインスタンス、およびエンドポイントの詳細については、「インスタンスのエンドポイントの表示」をご参照ください。

      product_key

      a18wP ******

      デバイス検証情報。 詳細については、「デバイス検証情報の取得」をご参照ください。

      この例では、デバイス固有証明書検証方法が使用されます。

      device_name

      LightSwitch

      device_secret

      uwMTmVAMnGGHaAkqmeDY6cHxxB ******

      protocol_version

      AIOT_MQTT_VERSION_5_0

      MQTTのバージョン番号として5.0を指定します。

      use_assigned_clientid

      1

      MQTT 5.0の [Assigned Client Identifier] 機能を使用する場合は、use_assigned_clientidパラメーターを1に設定します。

    • MQTTキープアライブメカニズムの説明:

      重要
      • キープアライブ期間中、デバイスはping要求を含む少なくとも1つのメッセージを送信する必要があります。

      • タイマーは、IoT PlatformがCONNECTメッセージへの応答としてCONNACKメッセージを送信するときに開始されます。 IoT PlatformがPUBLISH、SUBSCRIBE、PING、またはPUBACKメッセージを受信した場合、タイマーはリセットされます。 IoT Platformは、30秒ごとにMQTT接続のハートビートをチェックします。 ハートビートチェックの待機時間は、デバイスがIoT Platformに接続してから次のハートビートチェックが実行されるまでの期間です。 最大タイムアウト期間は、次の式を使用して計算されます。心拍間隔 × 1.5 + 心拍チェックの待ち時間。 サーバが最大タイムアウト期間内にデバイスからメッセージを受信しない場合、サーバはデバイスとの接続を終了する。

      Link SDK for Cは、キープアライブメカニズムを提供します。 次の表に、デバイス接続のカスタムハートビート関連の値を指定するために設定できるパラメーターを示します。 それ以外の場合は、デフォルト値が使用されます。

      項目

      デフォルト値

      説明

      AIOT_MQTTOPT_HEARTBEAT_MAX_LOST

      2

      失われる可能性のある心拍の最大数。 制限を超えると、システムは新しい接続を確立します。

      AIOT_MQTTOPT_HEARTBEAT_INTERVAL_MS

      25,000

      システムによって確立される切断と新しい接続の間隔。 有効な値: 1000〜1200000。 単位:ミリ秒。

      AIOT_MQTTOPT_KEEPALIVE_SEC

      1,200

      キープアライブ期間。 ハートビートが失われた後、システムは指定された期間内に新しい接続を確立できます。 有効値: 30〜1200。 単位は秒です。 300より大きい値を指定することを推奨します。

  2. ステータスを監視し、メッセージを受信するようにコールバックを設定します。

    1. ステータスを監視するコールバックを設定します。

      • サンプルコード:

        int main(int argc, char * argv[])
        {
         ...
         ...
        
         /* MQTTメッセージを受信するデフォルトのコールバックを指定します。  */
         aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_RECV_HANDLER, (void *)demo_mqtt_default_recv_handler);
         /* MQTTイベントを処理するコールバックを指定します。  */
         aiot_mqtt_setopt(mqtt_handle、AIOT_MQTTOPT_EVENT_HANDLER、(void *)demo_mqtt_event_handler);
         ...
         ...
        }
         
      • パラメーター:

        項目

        説明

        AIOT_MQTTOPT_RECV_HANDLER

        demo_mqtt_default_recv_handler

        メッセージが受信されると、コールバックが呼び出されて必要な操作が実行されます。

        AIOT_MQTTOPT_EVENT_HANDLER

        demo_mqtt_event_handler

        デバイス接続のステータスが変更されると、コールバックが呼び出されて必要な操作が実行されます。

    2. ステータスを監視するコールバックを定義します。

      重要
      • イベント処理に時間のかかるロジックを指定しないでください。 そうでない場合、パケットを受信するために使用されるスレッドがブロックされる。

      • ネットワーク例外、自動再接続、切断など、複数の原因による接続ステータスの変更。

      • 接続ステータスの変更を処理するには、ビジネス要件に基づいてTODOセクションのコードを変更します。

      /* MQTTイベントを処理するコールバック。 接続が作成、回復、または閉じられると、コールバックが呼び出されます。 イベント定義の詳細については、core/aiot_mqtt_api.hをご参照ください。  * /
      void demo_mqtt_event_handler(void * handle, const aiot_mqtt_event_t * event, void * userdata)
      {
       switch (event->type) {
       /* aiot_mqtt_connect操作を呼び出して、MQTTブローカーへの接続を確立します。  */
       ケースAIOT_MQTTEVT_CONNECT: {
       printf("AIOT_MQTTEVT_CONNECT\n");
       /* TODO: 接続を確立するロジックを指定します。 スレッドをブロックする可能性のある時間のかかる関数を呼び出さないでください。 */  */
       }
       break;
      
       /* ネットワーク例外により切断エラーが発生した場合、SDKはMQTTブローカーへの再接続要求を自動的に開始します。  */
       ケースAIOT_MQTTEVT_RECONNECT: {
       printf("AIOT_MQTTEVT_RECONNECT\n");
       /* TODO: 接続を再確立するロジックを指定します。 スレッドをブロックする可能性のある時間のかかる関数を呼び出さないでください。 */  */
       }
       break;
      
       /* ネットワーク例外により切断エラーが発生しました。 基になる読み取りまたは書き込み操作が失敗します。 ハートビート応答はMQTTブローカーから取得されません。  */
       ケースAIOT_MQTTEVT_DISCONNECT: {
       char * cause = (event->data.disconnect == AIOT_MQTTDISCONNEVT_NETWORK_DISCONNECT) ? (「ネットワーク切断」):
       (「ハートビート切断」);
       printf("AIOT_MQTTEVT_DISCONNECT: % s\n" 、原因);
       /* TODO: 切断の問題を処理するロジックを指定します。 スレッドをブロックする可能性のある時間のかかる関数を呼び出さないでください。 */  */
       }
       break;
      
       default: {
      
       }
       }
      }
       
    3. メッセージを受信するコールバックを定義します。

      重要
      • メッセージの処理に時間のかかるロジックを指定しないでください。 そうでない場合、パケットを受信するために使用されるスレッドがブロックされる。

      • 受信したメッセージを処理するには、ビジネス要件に基づいてTODOセクションのコードを変更します。

      /* MQTTメッセージを受信するために呼び出すことができるデフォルトのコールバック関数。 この関数は、SDKがMQTTブローカーからMQTTメッセージを受信し、カスタムコールバックが利用できないときに呼び出されます。 * /
      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("ハートビート応答 \n");
                  /* TODO: ハートビート応答をサーバーに送信するためのロジックを定義します。 ほとんどの場合、応答は送信されません。 */
              }
              break;
      
      
              ケース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: MQTTブローカーからサブスクリプション要求に応答を送信するためのロジックを定義します。 ほとんどの場合、応答は送信されません。 */
              }
              break;
              ケースAIOT_MQTTRECV_UNSUB_ACK: {
                  printf("unsuback, , packet id: % d\n" 、
                         packet->data.unsub_ack.packet_id);
                  /* TODO: MQTTブローカーからサブスクリプション要求に応答を送信するためのロジックを定義します。 ほとんどの場合、応答は送信されません。 */
              }
              break;
              ケース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;
      
      
              ケースAIOT_MQTTRECV_PUB_ACK: {
                  printf("puback, packet id: % d\n", packet->data.pub_ack.packet_id);
                  /* TODO: MQTTブローカーから報告されたQoS 1メッセージへの応答を送信するためのロジックを定義します。 通常、応答は送信されない。 */
              }
              break;
      
              ケースAIOT_MQTTRECV_CON_ACK: {
                  aiot_mqtt_props_print(packet->data.con_ack.props);
              }
              break;
              ケースAIOT_MQTTRECV_DISCONNECT: {
                  printf (「サーバー切断、理由コード: 0x % x\n」、packet->data. server_disconnect.reas_code);
              }
              break;
       
              default: {
      
      
              }
          }
      }

ステップ3: 接続を確立する

aiot_mqtt_connect_v5操作を呼び出して、IoT Platformに接続および認証リクエストを送信します。 パラメーターの設定方法については、「接続パラメーターの設定」をご参照ください。

説明

次のサンプルコードで指定されているMQTT_PROP_ID_USER_PROPERTYユーザープロパティの詳細については、「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);
/* MQTT 5.0を介してサーバーへの接続を確立します。 * /
res = aiot_mqtt_connect_v5(mqtt_handle, NULL, conn_props);
aiot_mqtt_props_deinit(&conn_props);
if (res < STATE_SUCCESS) {
    /* MQTT接続の確立に失敗した場合は、MQTTインスタンスのリソースを解放します。 */
    aiot_mqtt_deinit(&mqtt_handle);
    printf("aiot_mqtt_connect failed: -0x % 04X\n\r\n", -res);
    printf (「デモ \r\nのmqtt_host、produt_key、device_name、device_secretなどの変数を確認してください」);
    リターン-1;
} 

ステップ4: keep-aliveスレッドの有効化

aiot_mqtt_process操作を呼び出して、ハートビートメッセージをMQTTブローカーに送信し、応答が生成されていないQoS 1メッセージを再送信します。 このようにして、永続的な接続が可能になる。

  1. キープアライブスレッドを有効にします。

    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. キープアライブスレッドを管理するには、次の関数を定義します。

    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;
            }
            睡眠 (1);
        }
        NULLを返します。} 

ステップ5: メッセージを受信するスレッドを有効にする

ブローカーからMQTTメッセージを受信するには、aiot_mqtt_recv操作を呼び出します。 必要な操作は、コールバックを使用してメッセージを受信することによって実行されます。 切断と自動再接続が発生した場合、必要な操作はコールバックを使用してイベントを処理します。

  1. スレッドがメッセージを受信できるようにします。

        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. スレッドを管理するには、次の関数を定義します。

    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;
                }
                睡眠 (1);
            }
        }
        NULLを返します。} 

ステップ6: トピックの購読

aiot_mqtt_sub_v5操作を呼び出して、指定したトピックをサブスクライブします。

  • サンプルコード:

    /* ビジネス要件に基づいてMQTT経由でトピックをサブスクライブする方法を示すサンプルコードを使用します。 */
        {
            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);
            /* サブスクリプションオプション。 */
            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;
            }
        }
    説明
    • 次のコードで指定されているMQTT_PROP_ID_USER_PROPERTYユーザープロパティの詳細については、「mqtt_property_identify_t」をご参照ください。

    • サブスクリプションオプションの指定方法の詳細については、「sub_options_t」をご参照ください。

  • パラメーター:

    パラメーター

    説明

    sub_topic

    /a18wP ******/LightSwitch /ユーザー /取得

    デバイスがサブスクライブ権限を持つトピック。 説明:

    • a1oGs ****** はデバイスのProductKeyです。

    • LightSwitchは、デバイスのDeviceNameです。

    この例では、デフォルトのカスタムトピックが使用されます。

    デバイスは、このトピックを使用してIoT Platformからメッセージを受信できます。

    詳細については、「トピック」をご参照ください。

    sub_props

    aiot_mqtt_props_init()

    サブスクリプションに指定する追加のプロパティ。

    opts

    . no_local = 1,

    . qos = 1、

    . retain_as_publish = 1、

    . retain_handling = 1、

    サブスクリプションオプション。

ステップ7: メッセージを送信

aiot_mqtt_pub_v5操作を呼び出して、指定したトピックにメッセージを送信します。

  • サンプルコード:

    mqtt_properties_t * pub_props = aiot_mqtt_props_init();
      /* ビジネス要件に基づいてMQTT経由でメッセージを送信する方法を示すサンプルコードを使用します。* /
      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;
       }
    説明

    次のコードで指定されているMQTT_PROP_ID_USER_PROPERTYユーザープロパティの詳細については、「mqtt_property_identify_t」をご参照ください。

  • パラメーター:

    パラメーター

    説明

    pub_topic

    /a18wP ******/LightSwitch /ユーザー /アップデート

    発行権限を持つトピック。 説明:

    • a1oGs ****** は、デバイスのProductKeyを示します。

    • LightSwitchは、デバイスのDeviceNameを示します。

    デバイスは、このトピックを使用してIoT Platformにメッセージを送信します。

    詳細については、「トピック」をご参照ください。

    pub_payload

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

    IoT Platformに送信するメッセージの内容。

    この例では、カスタムトピックが使用されています。 したがって、カスタムメッセージ形式を指定できます。

    詳細については、「データ形式」をご参照ください。

    pub_props

    詳細については、サンプルコードをご参照ください。

    メッセージに含まれるプロパティ。

デバイスとIoT Platform間のMQTT接続が確立されたら、メッセージ数がしきい値を超えないようにします。

  • 通信制限の詳細については、「制限」をご参照ください。

  • メッセージ数がしきい値を超えた場合は、IoT Platformコンソールにログインして、蓄積されたメッセージを表示します。 詳細については、「コンシューマーグループの表示と監視」をご参照ください。

ステップ8: IoT Platformからデバイスを切断する

aiot_mqtt_disconnect_v5操作を呼び出して、デバイスをIoT Platformから切断します。

次のサンプルコードで指定されているMQTT_PROP_ID_USER_PROPERTYユーザープロパティの詳細については、「mqtt_property_identify_t」をご参照ください。

説明

MQTT接続は、永続的に接続されたままのデバイスに適用されます。 IoT Platformからデバイスを切断できます。 この例では、メインスレッドを使用してパラメータを設定し、接続を確立します。 接続が確立されたら、メインスレッドをスリープ状態にすることができます。

    {
        mqtt_properties_t * disconn_props = aiot_mqtt_props_init();
        /* 理由コード0x0は正常な切断を示します。 */
        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);
    }

ステップ9: プログラムを終了する

aiot_mqtt_deinit操作を呼び出して、MQTTクライアントインスタンスを削除し、対応するリソースをリリースします。

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

次に何をすべきか

  • サンプルコードファイルを設定したら、ファイルをコンパイルして実行可能ファイルを生成します。 この例では、。/output/mqtt-v5-basic-デモ実行ファイルが生成されます。

    詳細については、「環境の準備」をご参照ください。

  • 実行結果の詳細については、「ログの表示」をご参照ください。