Skip to content

Instantly share code, notes, and snippets.

@rlaguilar
Created May 19, 2026 12:22
Show Gist options
  • Select an option

  • Save rlaguilar/cfff4cbe216767ece63ad06c0ed697d6 to your computer and use it in GitHub Desktop.

Select an option

Save rlaguilar/cfff4cbe216767ece63ad06c0ed697d6 to your computer and use it in GitHub Desktop.
Replacement for the the ESP32 SimpleWiFiServer sample code to improve latency on iOS devices.
// Replacement for the the ESP32 SimpleWiFiServer sample code to improve latency on iOS devices.
// Cause of the delay: iOS Safari opens a speculative TCP connection before sending the real HTTP request when you tap a link.
// The fix: early-exit on a silent client.
void loop() {
NetworkClient client = server.available();
if (!client) return;
// Wait briefly for the request line to arrive.
unsigned long start = millis();
while (!client.available() && client.connected() && millis() - start < 10) {
delay(1);
}
// If the client connected but sent nothing, it's a speculative preconnect.
// Drop it immediately — don't waste cycles parsing or responding.
if (!client.available()) {
client.stop();
return;
}
// Read just the first line: "GET /path HTTP/1.1"
String requestLine = client.readStringUntil('\n');
requestLine.trim();
Serial.print("Request line: ");
Serial.println(requestLine);
// Extract the path (between the two spaces).
int firstSpace = requestLine.indexOf(' ');
int secondSpace = requestLine.indexOf(' ', firstSpace + 1);
String path = (firstSpace >= 0 && secondSpace > firstSpace)
? requestLine.substring(firstSpace + 1, secondSpace)
: "/";
Serial.print("Path: ");
Serial.println(path);
if (path.endsWith("/H")) {
digitalWrite(5, HIGH); // GET /H turns the LED on
}
if (path.endsWith("/L")) {
digitalWrite(5, LOW); // GET /L turns the LED off
}
// Drain remaining request data without parsing it.
// This is important: iOS may send body/headers we don't care about,
// but the socket needs to be clear before we respond.
while (client.available()) client.read();
// Send a complete, well-formed response with explicit length and close.
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
// the content of the HTTP response follows the header:
client.print("<meta name='viewport' content='initial-scale=1.0, width=device-width'>");
client.print("Click <a href=\"/H\">here</a> to turn the LED on pin 5 on.<br>");
client.print("Click <a href=\"/L\">here</a> to turn the LED on pin 5 off.<br>");
client.println();
client.stop();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment