2016-12-29 177 views
1

我打电话给一个使用ESP8266 WiFi芯片的api。 Im声明一个全局变量来分配服务器向它发送的令牌。变量赋值是在while循环内进行的。在这个循环中,我正在读取“令牌”回复的内容并将其保存在全局变量中。 但是,当我打印出while循环以外的结果变量是空的。但在循环内部不是。全局变量内部while循环在循环外不可用

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

你确定在上一次迭代中deviceToken是非空的吗?你能否有效地在最后调用'Serial.print(“”)'一次或多次,导致这个问题? – Phylogenesis

+0

@Phylogenesis是似乎这是问题,当我删除令牌打印它删除后的“0”。 –

回答

2

在while循环,你是通过线循环的HTTP标头和数据线,并覆盖每个时间deviceToken。这是可以的,除了每行以\r\n结尾,而不仅仅是\r - (同样,你可能只想把标记写入eeprom,而不是每个标题)。

所以读取的最后一个标记是一个单独的\n然后放入deviceToken。您需要在每行之后读取额外的字节。

一种替代的方法是将读,直到到达\r\n\r\n(报头块的结束),那么读取的大小(28进制 - 这是一个chunked transfer),然后就可以读取和存储所需的令牌。否则,您的令牌将是最后一个0或它后面的换行符。

另外请记住,不能保证答复总是会被分块(在这种情况下实际上很奇怪),并且您也应该为“正常”答复做好准备。

解决这个问题的简单方法是发送HTTP/1.0请求,而不是HTTP/1.1(只要该服务器支持它)。由于HTTP/1.0不支持/允许分块传输,因此您在回复中始终会有一个'干净'deviceToken

+0

这就是我正在等待的答案。 Thankss。我现在想要做的是使用'\ n'。并且在循环外部删除了writeToEEPROM。我认为它是这样工作的。令牌被添加到下一个url字符串中以创建新的API调用。但不幸的是,我收到400个不好的请求。我在邮递员的串行测试打印的网址,它工作正常。 –

+0

@KeghamK。您的令牌现在可能有一个尾随的'\ r',这可能导致错误的请求。 –

+0

@KeghamK。使用HTTP/1.0代替也可能更好/更容易 - 查看更新后的答案。 –

0

感谢Danny_ds指示,我能解决我的问题,并想到在这里共享工作代码作为参考。

// 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; 
    }