Сериализация JSON в качестве ответа на HTTP-запрос

Я хочу, чтобы мой ESP8266 предоставлял некоторые конечные точки JSON. Я хочу использовать ArduinoJson для сериализации. Хотя в целом это работает, если я сериализую в строку и потом верну эту строку, мне было интересно, действительно ли нет способа сделать это, не тратя впустую так много памяти. Разве нельзя сделать что-то подобное? Есть подсказки?

ESP8266WebServer server;
StaticJsonDocument<768> response;
response["night"] = _playback.isNight();
response["shuffle"] = _playback.isShuffle();
server.send_P(200, "application/json", NULL);
serializeJson(response, server.client());

(это дает следующую ошибку:)

no instance of overloaded function "serializeJson" matches the argument list -- argument types are: (ArduinoJson6141_0000010::StaticJsonDocument<768U>, WiFiServer::ClientType)

, 👍1

Обсуждение

Вы смотрели документацию ArduinoJson? Ты пробовал? Это сработало? Если нет, то какие ошибки вы получили?, @Edgar Bonet

Да, я сделал. Да, я пытался. Нет, это не так. Я добавил сообщение об ошибке., @Nitek

вы можете просто построить его как строку. imho, большим преимуществом json lib является синтаксический анализ, а не сериализация., @dandavis

Странный. WiFiServer::ClientType [определяется как WiFiClient](https://github.com/esp8266/Arduino/blob/2.6.3/libraries/ESP8266WiFi/src/WiFiServer.h#L65), который [наследует от Client](https://github.com/esp8266/Arduino/blob/2.6.3/libraries/ESP8266WiFi/src/WiFiClient.h#L45), который [наследует от Stream](https://github .com/esp8266/Arduino/blob/2.6.3/cores/esp8266/Client.h#L26), который [наследует от Print](https://github.com/esp8266/Arduino/blob/2.6.3 /cores/esp8266/Stream.h#L38), к которому вы должны иметь возможность сериализоваться. Не могли бы вы попробовать сериализовать в Serial, просто чтобы посмотреть, работает ли он?, @Edgar Bonet

Это то, о чем я думал! Я сериализовал в char[], и он отлично работает, @Nitek


1 ответ


Лучший ответ:

2

serializeJson() принимает Print&, то есть ссылка на класс, реализующий интерфейс Print.

WiFiClient реализует интерфейс Print, но serializeJson() не может ссылаться на него, потому что ESP8266WebServer::client() возвращает временное значение. Действительно, C++ запрещает ссылки на временные переменные, разрешены только const ссылки на временные переменные.

Чтобы исправить эту ошибку компиляции, необходимо извлечь переменную:

WiFiClient client = server.client();
serializeJson(doc, client);

На мой взгляд, ESP8266WebServer::client() должен возвращать WiFiClient& вместо WiFiClient, как и HTTPClient::getStream() делает. Я открыл по этому поводу issue #7075.

В любом случае, даже если это исправит компиляцию, я не уверен, что она будет работать так, как вы задумали, потому что ESP8266WebServer может не разрешать запись напрямую в WiFiClient. р>

,