簡體   English   中英

使用 C 和 ESP-IDF 框架通過 MQTT 將 JSON 對象從 ESP32 發布到 AWS IoT

[英]Publishing JSON object through MQTT to AWS IoT from ESP32 using C and ESP-IDF framework

我有一個 IoT_Publish_Message_Params 結構,需要准備它以准備在 AWS IoT 上發布。 當我將字符串作為有效負載傳遞時,以下代碼段完全正常。

/**
 * @brief Publish Message Parameters Type
 *
 * Defines a type for MQTT Publish messages. Used for both incoming and out going messages
 *
 */
typedef struct {
    QoS qos;        ///< Message Quality of Service
    uint8_t isRetained; ///< Retained messages are \b NOT supported by the AWS IoT Service at the time of this SDK release.
    uint8_t isDup;      ///< Is this message a duplicate QoS > 0 message?  Handled automatically by the MQTT client.
    uint16_t id;        ///< Message sequence identifier.  Handled automatically by the MQTT client.
    void *payload;      ///< Pointer to MQTT message payload (bytes).
    size_t payloadLen;  ///< Length of MQTT payload.
} IoT_Publish_Message_Params;

IoT_Publish_Message_Params paramsQOS0;
sprintf(cPayload, "%s : %d ", "Hello from HOME!!", i);

paramsQOS0.qos = QOS0;
paramsQOS0.payload = (void *) cPayload;
paramsQOS0.isRetained = 0;
paramsQOS0.payloadLen = strlen(cPayload);
rc = aws_iot_mqtt_publish(&client, TOPIC, TOPIC_LEN, &paramsQOS0);

現在我想發送一個實際的 JSON 有效負載,但我不確定如何做到這一點。 我嘗試使用 cJSON 創建一個 JSON 對象:

cJSON *root,*fmt;
root=cJSON_CreateObject();
paramsQOS0.payload = (void *) root
cJSON_AddItemToObject(root, "response", fmt=cJSON_CreateObject());
cJSON_AddNumberToObject(fmt,"hello", 123);
cJSON_AddNumberToObject(fmt,"bye", 321);

但是,我的問題是,我在這里作為 IoT_Publish_Message_Params.payloadLen 傳遞什么? 以及如何將 json 對象傳遞給 IoT_Publish_Message_Params.payload?

在我看來,您有兩種選擇。 將 JSON 作為字符串或原始字節發送。

如果您想將其作為字符串發送(例如{"CarType":"BMW","carID":"bmw123"} ),那么您希望將其轉換為字符串。 在這里找到了一些代碼。

char* str = cJSON_Print(root);  
paramsQOS0.payload = (void *) str;
paramsQOS0.payloadLen = strlen(str);

但是,將其作為原始字節發送會更有效。 為此,您需要一個指向對象開頭的指針,以及以字節為單位的對象大小。 快速掃描GitHub 頁面,我發現cJSON_GetArraySize顯然返回了對象大小。

然后它應該看起來像這樣:

paramsQOS0.payload = (void *) root;
paramsQOS0.payloadLen = cJSON_GetArraySize(root); // Not sure about this one

免責聲明,我沒有使用過 cJSON,也沒有測試過代碼。 我想告訴你該走哪個方向。

IoT_Publish_Message_Params具有payloadpayloadLen成員,因此您可以提供要發送的任何有效內存和字節長度。 在您的第一個示例中,您提供了一個靜態分配的字符串及其長度。

JSON 是基於字符串的編碼協議,因此payload將是一個char指針,並且payloadLen可以使用strlen計算。

cJSON_Print返回對象的 json 字符串,使用它返回的指針並將其分配給payload

請閱讀cJSON API 文檔如何使用它。 下面是如何使用修改代碼來發送 JSON 字符串。

IoT_Publish_Message_Params paramsQOS0;
char *json_str;

/* create a json message */
cJSON *root, *response;
root = cJSON_CreateObject();
response = cJSON_CreateObject();
cJSON_AddItemToObject(root, "response", response);
cJSON_AddNumberToObject(response, "hello", 123);
cJSON_AddNumberToObject(response, "bye", 321);

json_str = cJSON_Print(root);
if (json_str != NULL)
{
    paramsQOS0.qos = QOS0;
    paramsQOS0.isRetained = 0;
    paramsQOS0.payload = json_str;
    paramsQOS0.payloadLen = strlen(json_str);
    rc = aws_iot_mqtt_publish(&client, TOPIC, TOPIC_LEN, &paramsQOS0);
    free(json_str);
}

cJSON_Delete(root);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM