NodeMcu 使用 WiFiClientSecure readStringUntil() 需要 15 秒才能完成

NodeMcu using WiFiClientSecure readStringUntil() taking 15 seconds to complete

我有以下代码:

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 秒才能完成,我不确定为什么。我可以在 Web 浏览器中使用相同的请求,它会立即返回。特别是 net.readStringUntil 似乎在花时间。

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

更新 2:我发现了问题。请参阅下面的答案。

好的,我将其放入以进行澄清。每个示例都为 readStringUntil() 显示“\r”,这可能会造成混淆。所以如果你使用 '\r' 那么下一次读取将以 '\n' 开头,所以如果你正在寻找 headers 的结尾,它实际上是 '\n\r\n' 因为从先前读取的行结转。那么会发生什么情况是您的数据与 crlfs 不同步。我发现使用“\n”作为终止符效果更好,因为 headers 的标准格式以“\r\n”结尾。然后,您可以通过仅查找 '\r'(\n 终止符被 readStringUntil() 吃掉)来测试 headers 的结尾。然后你可以开始另一个循环来获取你的数据。然后一切正常,不需要 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);