Created
May 19, 2026 12:22
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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