NodeMcu使用WiFiClientSecure readStringUntil()花费15秒完成

时间:2018-04-12 17:31:49

标签: arduino-esp8266

我有以下代码:

if (net.connect(host, port)) {
  String req = "GET /curTemp?temp=" + String(temperatureFahrenheit) + " HTTP/1.1\r\n" + 
               "Host: " + host + "\r\n" +
               "Authorization: Basic xxxxxxxxxxxxxxxxx\r\n" +
               "Connection: close\r\n\r\n";
  net.print(req);

  // Get headers
  while (net.connected()) {
    String line = net.readStringUntil('\r');
    if (line == "\r") {
      break;
    }
  }

  // Get temperature
  StaticJsonBuffer<50> jsonBuffer;
  JsonObject& root = jsonBuffer.parseObject(net.readStringUntil('\r'));
  const char* temp = root["temp"];
  Serial.print("Temp:");
  Serial.println(temp);
} else {      
  Serial.println("connection failed");
}

这需要15秒才能完成,我不知道为什么。我可以在网络浏览器中使用相同的请求,它会立即返回。具体来说,net.readStringUntil似乎需要时间。

更新:我通过设置setTimeout(1000)找到了一种解决方法,但我不明白为什么这是必要的。请求是否应该关闭连接并且readStringUntil()在完成时终止?也许我不了解WiFiClientSecure?

UPDATE2:我发现了问题。见下面的答案。

1 个答案:

答案 0 :(得分:0)

好的,我正在澄清这一点。每个例子都显示了&#39; \ r&#39;对于readStringUntil(),这可能会令人困惑。那么如果您使用&#39; \ r&#39;然后下一次阅读将以&#39; \ n&#39;开头。因此,如果您正在寻找标题的结尾,它实际上将是&#39; \ n \ r \ n&#39;因为从先前读取的行继续进行。那么你的数据与crlfs不同步会发生什么。我发现使用&#39; \ n&#39;对于终结器工作得更好,因为标头的标准格式以&#39; \ r \ n&#39;结尾。然后,您可以通过查找&#39; \ r&#39;来测试标题的结尾。 (\ n终止符被readStringUntil()吃掉)。然后,您可以启动另一个循环来获取数据。然后一切正常,不需要setTimeout。

示例:

if (net.connect(host, port)) {
  String req = "GET /curTemp?temp=" + String(temperatureFahrenheit) + " HTTP/1.1\r\n" + 
               "Host: " + host + "\r\n" +
               "Authorization: Basic dXNlcjpkYWYxMjM0\r\n" +
               "Connection: close\r\n\r\n";
  net.print(req);

  delay(1000);

  // Get headers
  while (net.available()) {

    // Note \n for terminator
    String line = net.readStringUntil('\n');

    // Only \r because \n is eaten by readStringUntil()
    if (line == "\r") {
      break;
    }
  }

  // Now look for data (in my case only one line of JSON)

  // No \r\n on this one.
  String line = net.readStringUntil('}');

  // Put back the character eaten by readStringUntil()
  line = line + "}";

  Serial.println(line);