このトピックでは、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の初期化
ヘッダーファイルを追加します。
を含む# 「aiot_state_api.h」を含める # 「aiot_sysdep_api.h」を含む # 「aiot_mqtt_api.h」基になる依存関係を追加し、ログ出力機能を設定します。
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile); aiot_state_set_logcb(demo_state_logcb);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」をご参照ください。
接続パラメータを設定します。
サンプルコード:
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より大きい値を指定することを推奨します。
ステータスを監視し、メッセージを受信するようにコールバックを設定します。
ステップ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メッセージを再送信します。 このようにして、永続的な接続が可能になる。
キープアライブスレッドを有効にします。
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; }キープアライブスレッドを管理するには、次の関数を定義します。
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操作を呼び出します。 必要な操作は、コールバックを使用してメッセージを受信することによって実行されます。 切断と自動再接続が発生した場合、必要な操作はコールバックを使用してイベントを処理します。
スレッドがメッセージを受信できるようにします。
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; }スレッドを管理するには、次の関数を定義します。
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;
}