2016-12-29 5 views
1

Ich rufe eine API mit ESP8266 WiFi-Chip. Ich deklariere eine globale Variable, um das vom Server gesendete Token diesem zuzuweisen. Die Variablenzuordnung erfolgt innerhalb einer while-Schleife. In dieser Schleife lese ich den Inhalt der Antwort "das Token" und speichere es in der globalen Variable. Aber wenn ich das Ergebnis außerhalb der While-Schleife zu Variable drucken ist leer. Aber innerhalb der Schleife ist es nicht.Globale Variable zugewiesen innerhalb While-Schleife nicht verfügbar außerhalb der Schleife

String deviceToken; 

WiFiClient client; 

    if (!client.connect(hostIp, 80)){ 
    Serial.println("Connection to server failed."); 
    Serial.print(client.connect(hostIp, 80)); 
    return; 
    } 

    String authURL = "/api/"; 
     authURL += "startauth/"; 
     authURL += serialValue; 
     Serial.print("Requesting URL: "); 
     Serial.println(authURL); 

     // This will send auth request to the server 
     client.print(String("GET ") + authURL + " HTTP/1.1\r\n" + 
        "Host: " + host + "\r\n" + 
        "Connection: close\r\n\r\n"); 
    unsigned long timeout = millis(); 
    while (client.available() == 0) { 
     if (millis() - timeout > 5000) { 
      Serial.println(">>> Client Timeout !"); 
      client.stop(); 
      return; 
     } 
    } 
    // Read Auth reply from server and print them to Serial 
     while(client.available()){ 
     String token = client.readStringUntil('\r'); 
     deviceToken = token; 
     writeDeviceToken(token.c_str()); //Function to write data in eeprom 
     Serial.print(deviceToken); //NOT EMPTY 
     } 

     Serial.print("Device Token:" + deviceToken); //EMPTY VARIABLE 

enter image description here

+0

Sind Sie * sicher *, dass das 'deviceToken' in der letzten Iteration nicht leer ist? Könnten Sie tatsächlich 'Serial.print (" ")' ein oder mehrere Male am Ende aufrufen, was dieses Problem verursacht? – Phylogenesis

+0

@Phylogenesis scheint ja das ist das Problem, wenn ich das Token löschte, löschte es die "0" danach. –

Antwort

2

In Ihrer while-Schleife Schleifen Sie über die HTTP-Header und die Daten Zeile für Zeile und deviceToken jedes Mal überschrieben werden. Das ist ok, außer dass jede Zeile mit \r\n endet und nicht nur \r - (Sie wollen wahrscheinlich nur das Token auf den EEPROM schreiben, nicht jeden Header).

Also das letzte Token, das gelesen wird, ist eine einzige \n, die dann in deviceToken gesetzt wird. Sie müssen dieses zusätzliche Byte nach jeder Zeile lesen.

Ein alternativer Weg wäre zu lesen, bis Sie \r\n\r\n (Ende des Headerblocks) erreichen, dann lesen Sie die Größe (28 hex - das ist ein chunked transfer), und dann können Sie das gewünschte Token lesen und speichern. Andernfalls wäre Ihr Token der letzte 0 oder der darauffolgende Zeilenumbruch.

Denken Sie auch daran, dass es keine Garantie gibt, dass die Antwort immer chunked wird (was in diesem Fall eigentlich ziemlich seltsam ist), und Sie sollten auch auf eine "normale" Antwort vorbereitet sein.

Eine einfache Möglichkeit, dies zu beheben, ist eine HTTP/1.0 Anfrage anstelle von HTTP/1.1 Anfrage zu senden (soweit dieser Server es unterstützt). Da HTTP/1.0 keine Chunked-Übertragungen unterstützt/erlaubt, haben Sie immer eine 'saubere' deviceToken in der Antwort.

+0

Das war die Antwort, auf die ich gewartet habe. Danke. Was ich jetzt versuchte, ist '\ n'. Und entfernt das writingToEEPROM außerhalb der Schleife. Und ich denke, es funktioniert so. Das Token wird in der nächsten URL-Zeichenfolge hinzugefügt, um einen neuen API-Aufruf zu erstellen. Aber leider bekomme ich 400 schlechte Anfragen. Ich habe die gedruckte URL auf der Seriennummer im Briefträger getestet, es funktioniert einwandfrei. –

+0

@KeghamK. Ihr Token hat wahrscheinlich gerade ein nachstehendes '\ r', was die fehlerhafte Anfrage verursachen könnte. –

+0

@KeghamK. Es könnte auch besser/einfacher sein, stattdessen 'HTTP/1.0' zu verwenden - siehe aktualisierte Antwort. –

0

Dank Danny_ds Anweisungen war ich in der Lage, mein Problem zu lösen und dachte daran, den Arbeitscode hier als Referenz zu teilen.

// Read Auth reply from server and print them to Serial 
    while(client.available()){ 

     char c = client.read(); 
     response += c; 
    } 
    String testStatus = response; 
    if((strstr(testStatus.c_str(),"HTTP/1.1 500")) != NULL) { 
    Serial.println("Found reponse 500"); 
    return; 

    } else if ((strstr(testStatus.c_str(),"HTTP/1.1 200")) != NULL) { 
     Serial.println("Found reponse 200"); 
     //Grabing the token after the header 
     String token = response.substring(response.indexOf("\r\n\r\n") + 8); 
     //Removing the \r in end of token 
     token.remove(40); 
     deviceToken = token; 
     writeDeviceToken(deviceToken.c_str()); 
     delay(500); 
     Serial.print("Device Token:" + deviceToken); 
     return; 
    } 
Verwandte Themen