Синтаксический анализ ответа JSON из потока
Я хочу разобрать ответ JSON из запроса GET. Обычно я делаю это с помощью строковой переменной для хранения ответа и последующего анализа этой строки с помощью библиотеки ArduinoJson, как показано ниже:
#include <Arduino.h>
#include "OTA.h"
#include "Credentials.h"
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char url[] = "http://date.jsontest.com/";
HTTPClient getClient;
void getRequest(String &payload)
{
getClient.begin(url);
int httpCode = getClient.GET();
if (httpCode > 0)
{
payload = getClient.getString();
// Serial.print("HTTP Status: ");
// Serial.println(httpCode);
}
else
{
Serial.println("Error on HTTP request");
}
getClient.end();
}
void parseResponse(String &payload)
{
StaticJsonDocument<128> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error)
{
Serial.print("deserializeJson() failed: ");
Serial.println(error.c_str());
return;
}
const char *time = doc["time"]; // "03:53:25 AM"
// unsigned long *epoch = doc["milliseconds_since_epoch"]; // 1362196405309
const char *date = doc["date"]; // "03-02-2013"
Serial.println(date);
}
void setup()
{
setupOTA("ESP-N2", mySSID, myPASSWORD);
Serial.begin(115200);
}
void loop()
{
ArduinoOTA.handle();
unsigned long newTime = millis();
static unsigned long oldTime = 0;
String payload;
if (newTime - oldTime >= 5000)
{
oldTime = newTime;
getRequest(payload);
parseResponse(payload);
Serial.println();
}
}
Я хочу избежать использования String и ArduinoJson offician reference page упоминает, что можно десериализовать непосредственно из входного потока, например, WiFiClient, ethernetclient или serial, но я не смог найти ни одного примера, показывающего его использование. Поэтому мне любопытно узнать, как им пользоваться.
Исходя из моего базового понимания потока, я полагаю, что мне нужно определить буфер или ячейку памяти, которая будет содержать входящие байты и, используя адрес этого буфера, должна считывать данные по битам. Так нужно ли мне делать что-то вроде этого:
char buffer[]= httpClient.getStream();
а затем передать этот буфер в качестве входных данных в функцию десериализации? или я совершенно неправильно понял?
@Zaffresky, 👍0
Обсуждение1 ответ
Лучший ответ:
HttpClient.GetStream()
возвращает экземпляр Stream
, который можно передать в deserializeJson()
, например:
deserializeJson(doc, httpClient.getStream());
Однако, поступая таким образом, вы обходите код в HttpClient
, который обрабатывает фрагментированную кодировку передачи, поэтому вы должны вызвать HttpClient.useHTTP10(true)
перед вызовом GET
, чтобы убедиться, что сервер не вернет фрагментированный ответ.
Смотрите, как использовать ArduinoJson с HttpClient?
Большое спасибо за объяснение. Я рад узнать об использовании потока. Это работает хорошо, но я также получаю [D][HttpClient.cpp:378] disconnect(): все еще данные в буфере (1), очистить. [D][HttpClient.cpp:387] disconnect(): tcp stop. Поскольку я читаю все потоковые данные, к каким данным это может относиться? Может ли это вызвать такую проблему, как утечка памяти или фрагментация?, @Zaffresky
Я добавил ChunkedStreamReader в свой StreamLib. он обертывает входной поток и декодирует фрагментированный ввод: https://github.com/jandrassy/StreamLib/blob/b9b31e7908479efd0149940df9de610439532506/examples/Advanced/ReadChunkedJSON/ReadChunkedJSON.ino#L36, @Juraj
Я следовал подходу, упомянутому в документации, но кажется, что мои запросы GET не работают, когда я использую http1.0. Мой сервер работает на aws (amplify) и использует http2. Что мне делать в этом случае?, @seddouguim
- ESP8266 Arduino Json object array десериализация в структуру
- Использование esp-wroom-32 без платы разработки
- Ошибка при загрузке «Произошла фатальная ошибка esptool.py: тайм-аут записи»
- NodeMCU (Arduino IDE) «DynamicJsonBuffer» не был объявлен в этой области
- Чтение файла из SPIFFS в nodemcu с использованием ArduinoJson
- Получение всех данных моего объекта JSON из Serial.read() сразу
- esp_now.h: нет такого файла или каталога
- Ошибка при загрузке кода в esp8266 через arduino (FatalError('Failed to connect to %s: %s' % (self.CHIP_NAME, last_error)))
https://arduinojson.org/v6/how-to/use-arduinojson-with-httpclient/, @Mat