Hi,
I am having a problem with the simple http server, on an esp32. It is running into long wait times or finally a timeout while waiting for the request line in *client.readStringUntil('\r') . *
When I call the page from a browser, the first request mostly runs flawlessly: client connects and the request line is received within very short time and it sends out the page. But then direcly after, the client is still connected and no request line is delivered so that the timeout expires and my program is blocked for a few secs. When favicon is requested, it is handled fast.
The prominent problem is, that the page calls and answeres always become interleaved. The server waits for the request line of a first call, but only when the page is called again, (I use an automatic refresh every 1 sec) this request line frees the process to proceed. For me it looks like a bug in the implementation of these http server functions. I'd love to use asynchronuous server functions, but I don't have implemented that yet.
This is a stripped down example without an automatic refresh of the page. You have to type the IP adress of your module into the address bar to call the page, and probably reload often. On the delivered page it shows how long it took to receive the request.
#include <WiFi.h> // for ESP32
//#include <ESP8266WiFi.h> //für esp8266
char chBuffer[128]; // general purpose character buffer
const char chPassword[] = "xxxxxx"; // your network password
const char chSSID[] = "yyyyyy"; // your network SSID
const char* NTPStr = "192.168.178.1"; // specify NTP IP
WiFiServer httpserver(80);
//--------------------------------------------------------------------------------------------
void httpserverfnct() {
WiFiClient client = httpserver.available(); //wir bekommen einen client der Daten zum Empfangen bereit hat server.avail liefert client
if (!client) {
return; //raus
} //kein client
//client ist verbunden, aber oft kein http request vorliegend
int bytesatstart = client.available(); //wieviele bytes des http requests sind verfügbar? Ausgabe unten über page
Serial.println(F("ein client ist da")); // hier meist noch keine bytes avail, nur ganz am Anfang
client.setTimeout(2); // Sekunden beis ESP32!!! gehört zu client.readStringUntil(), Daten immer nur von nächstem Aufruf?
// client.setTimeout(1500); //Millisekunden bei ESP8266!!!
// Read the first line of the request
unsigned long t1 = millis(); //wie lang dauert es bis request line kommt?
String req = client.readStringUntil('\r'); // i.A. GET / HTTP/1.1 nächste bytes 10 72 chr(10)=\n, chr(13)=\r, meist 1050ms Wartezeit,
//alles um einen Abruf verschoben? am ende client noch da aber keine Daten kommen mehr
//client.stop wenn timeout?
unsigned long timeto1stline = millis() - t1; //wie lang dauert es bis request line kommt?
Serial.print(F("Wartezeit: "));
Serial.println(timeto1stline); //Ausgabe auch über http Seite
Serial.print(F("first request line: "));
Serial.println(req);
bool reqok = ((req.indexOf(F("favicon")) == -1) && (req.indexOf(F("GET /")) != -1));
while (client.available()) { //client.avail liefert anzahl bytes
client.read();
} //request weglesen mehrere Zeilen
time_t tn = time(nullptr); //Uhrzeit für page
struct tm * tmPointer = localtime(&tn); // struct tm timeinfo;
strftime (chBuffer, sizeof(chBuffer), "%a, %d %b %Y %H:%M:%S", tmPointer); //formatierte Zeitangabe in chbuffer aus Einzelzahlen in &tmpointer
if (reqok) {
Serial.println(F("war ein HTTP req, page gesendet"));
client.print(F("HTTP/1.1 200 OK\r\n Content-Type: text/html\r\n\r\n"));
client.print(F("<!DOCTYPE html> <html> <head> <title>HTTP Polling Test</title></head> "));
client.print(F("<body><table style=\"width: 70%; margin-left: auto; margin-right: auto;\"><tbody style=\"text-align: center;\">"));
client.print(F("<tr><td>Bytes bei Verbindg vorliegend</td> <td>ms Zeit bis http request geliefert</td></tr>"));
client.print(F("<tr><td><h1><span style=\"color: #0000ff;\"> "));
client.print(bytesatstart);
client.print(F("</span></h1></td> <td><h1><span style=\"color: #0000ff;\"> "));
client.print(timeto1stline);
client.print(F("</span></h1></td></tr>"));
client.print(F("<tr><td> </td> <td> </td></tr>")); //leerzeile
client.print(F("<tr><td style=\"text-align: center;\" colspan=\"2\">Request line</td></tr>"));
client.print(F("<tr><td style=\"text-align: center;\" colspan=\"2\"><h1><span style=\"color: #0000ff;\"> "));
client.print(req);
client.print(F("</span></h1></td></tr>"));
client.print(F("<tr><td style=\"text-align: center;\" colspan=\"2\">Zeit/Datum</td></tr>"));
client.print(F("<tr><td style=\"text-align: center;\" colspan=\"2\"><h1><span style=\"color: #0000ff;\"> "));
client.print(chBuffer);
client.print(F("</span></h1></td></tr>"));
client.print(F("</tbody></table></body></html> "));
} //GET HTTP
else {
Serial.println(F("war kein HTTP req")); //favicon wird nur 1x abgefragt
client.print(F("HTTP/1.1 404 Not Found"));
}
client.flush(); // Waits until all outgoing characters in buffer have been sent.
if (!client.connected()) {
client.stop();
Serial.println(F("ciao"));
} //client gegangen
} //httpservfnct
//--------------------------------------------------------------------------------------------
void setup() {
Serial.begin(115200);
while (!Serial)
{ } //warten
Serial.println("connecting WiFi"); //stat auf serial
WiFi.begin(chSSID, chPassword);
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(200);
}
Serial.println();
Serial.printf("WiFi connected to %s \r\n", chSSID); //stat auf serial
//configTime("CET-1CEST,M3.5.0/02,M10.5.0/03", NTPStr); //"de.pool.ntp.org" esp8266
configTime(0, 0, NTPStr); // esp32
setenv("TZ", "CET-1CEST,M3.5.0/02,M10.5.0/03" , 1); // esp32
char chIp[81];
WiFi.localIP().toString().toCharArray(chIp, sizeof(chIp) - 1);
Serial.printf("eigene IP : %s \r\n", chIp);
httpserver.begin();
Serial.println(F("http Server started"));
} //setup end
//-----------------------------------------------------------------------------------------
void loop() {
httpserverfnct(); //jedes mal nachschauen
} //loop