2016-06-06 6 views
1

Я программирую esp8266 с использованием Arduino IDE. Я присоединяюсь к локальной сети через WIFI. В конечном счете, я хочу загрузить контент JSON, сгенерированный на локальном сервере. Я использую код:arduino ide esp8266 json decode от URL

#include <ESP8266WiFi.h> 
    #include <ArduinoJson.h> 

    const char* ssid  = "NeoRaf"; 
    const char* password = "password"; 
    const char* host = "192.168.1.8"; 

    void setup() { 
     Serial.begin(115200); 
     delay(100); 

     // We start by connecting to a WiFi network 

     Serial.println(); 
     Serial.println(); 
     Serial.print("Connecting to "); 
     Serial.println(ssid); 

     WiFi.begin(ssid, password); 

     while (WiFi.status() != WL_CONNECTED) { 
     delay(500); 
     Serial.print("."); 
     } 

     Serial.println(""); 
     Serial.println("WiFi connected"); 
     Serial.println("IP address: "); 
     Serial.println(WiFi.localIP()); 

     //----------------------- 
     delay(5000); 

     Serial.print("connecting to "); 
     Serial.println(host); 

     // Use WiFiClient class to create TCP connections 
     WiFiClient client; 
     const int httpPort = 8095; 
     if (!client.connect(host, httpPort)) { 
     Serial.println("connection failed"); 
     return; 
     } 

     // We now create a URI for the request 
     String url = "/api"; 
     Serial.print("Requesting URL: "); 
     Serial.println(url); 

     // This will send the request to the server 
     client.print("GET " + url + " HTTP/1.1\r\n" + 
        "Host: " + host + "\r\n" + 
        "ApiCode: 8273\r\n" + 
        "Content-Type: application/json\r\n" + 
        "Connection: close\r\n\r\n"); 
     delay(500); 
     char c[1024]; 
     // Read all the lines of the reply from server and print them to Serial 
     while(client.available()){ 
      c[0] = client.read(); 

     //Serial.print(c); 

    Serial.print(c); 
    } 
     StaticJsonBuffer<200> jsonBuffer; 
     JsonObject& root = jsonBuffer.parseObject(c); 
     int data = root["lowVersion"]; 
     Serial.println(); 
     Serial.print(data); 

     Serial.println(); 
     Serial.println("closing connection"); 
    } 

    void loop() 
    {} 

Результат таков:

Connecting to NeoRaf 
    ...... 
    WiFi connected 
    IP address: 
    192.168.1.21 
    connecting to 192.168.1.8 
    Requesting URL: /api 
    HTTP/1.1 200 OK 
    Content-Length: 32 
    Content-Type: application/json 
    Server: Microsoft-HTTPAPI/2.0 
    Access-Control-Allow-Origin: * 
    Date: Mon, 06 Jun 2016 16:50:48 GMT 
    Connection: close 

{"lowVersion":1,"highVersion":3} 
0 
closing connection 

Эта строка JSON:

{"lowVersion":1,"highVersion":3} 

Так он должен отображать 1 и отображает 0. я не знать, как избавиться от заголовка:

HTTP/1.1 200 OK 
Content-Length: 32 
Content-Type: application/json 
Server: Microsoft-HTTPAPI/2.0 
Access-Control-Allow-Origin: * 
Date: Mon, 06 Jun 2016 16:50:48 GMT 

и как читать содержимое JSON (lowVersion или highVersion)?

ответ

1

Вам нужно определить, когда полезная нагрузка начинается в ответе HTTP. Таким образом, когда вы читаете данные с клиента, вы можете пропустить все строки заголовков HTTP. Кстати, в ответе JSON первый { обычно означает начало документа JSON.

httpbin пример

запрашивающие http://httpbin.org/get дает

{ 
    "args": {}, 
    "headers": { 
    ... 
    }, 
    "origin": "XXXXXXX", 
    "url": "http://httpbin.org/get" 
} 

Вы можете распечатать "url" поле следующим образом:

String json = ""; 
boolean httpBody = false; 
while (client.available()) { 
    String line = client.readStringUntil('\r'); 
    if (!httpBody && line.charAt(1) == '{') { 
    httpBody = true; 
    } 
    if (httpBody) { 
    json += line; 
    } 
} 
StaticJsonBuffer<400> jsonBuffer; 
Serial.println("Got data:"); 
Serial.println(json); 
JsonObject& root = jsonBuffer.parseObject(json); 
String data = root["url"]; 
+0

Не работает .... – Rafik73

0

Прежде всего, для обработки HTTP-запросов, вы можете использовать в библиотеке RestClient вместо написания всех запросов низкого уровня. Это экономит много времени и меньше подвержено ошибкам.

Например, для запроса GET, все, что вам нужно сделать, это:

String response = ""; 
int statusCode = client.get("/", &response); 

One good such library с поддержкой SSL написано пользователем GitHub DaKaz.

Вы можете использовать его для запроса GET. Возвращенный ответ будет без HTTP-заголовка. Функция вернет ответ с сервера без заголовков.

Теперь вы можете использовать библиотеку ArduinoJson по bblanchin для декодирования объекта JSON.

Детали можно увидеть here.

Или вы можете сделать простую строку manipuation, чтобы получить значение, хотя это не рекомендуется маршрут принять и склонен к ошибкам.

1

HTTP-заголовки всегда заканчиваются пустой строкой, поэтому вам просто нужно прочитать, пока не найдете два последовательных разрыва строки.

Посмотрите, например JsonHttpClient.inoArduinoJson «s, он использует Stream::find():

// Skip HTTP headers so that we are at the beginning of the response's body 
bool skipResponseHeaders() { 
    // HTTP headers end with an empty line 
    char endOfHeaders[] = "\r\n\r\n"; 

    client.setTimeout(HTTP_TIMEOUT); 
    bool ok = client.find(endOfHeaders); 

    if (!ok) { 
    Serial.println("No response or invalid response!"); 
    } 

    return ok; 
} 
Смежные вопросы