Skip to content

Commit e56cd84

Browse files
ESP8266WebServer - drop current HC_WAIT_READ connection sooner when another has data
Safari sometimes opens two connections when loading a page and only sends a request over the second one, resulting in a 5 second wait (HTTP_MAX_DATA_WAIT) before the request is processed. This commit drops the current connection after 30ms (HTTP_MAX_DATA_AVAILABLE_WAIT) when there is a new connection with data available or the buffer of pending TCP clients is full (currently 5).
1 parent 40876dc commit e56cd84

File tree

5 files changed

+40
-4
lines changed

5 files changed

+40
-4
lines changed

Diff for: doc/esp8266wifi/server-class.rst

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ Other Function Calls
4949
.. code:: cpp
5050
5151
bool hasClient ()
52+
size_t hasClientData ()
53+
bool hasMaxPendingClients ()
5254
bool getNoDelay ()
5355
virtual size_t write (const uint8_t *buf, size_t size)
5456
uint8_t status ()

Diff for: libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h

+11-4
Original file line numberDiff line numberDiff line change
@@ -335,11 +335,18 @@ void ESP8266WebServerTemplate<ServerType>::handleClient() {
335335
} // switch _parseRequest()
336336
} else {
337337
// !_currentClient.available(): waiting for more data
338-
if (millis() - _statusChange <= HTTP_MAX_DATA_WAIT) {
339-
keepCurrentClient = true;
338+
unsigned long timeSinceChange = millis() - _statusChange;
339+
// Use faster connection drop timeout if any other client has data
340+
// or the buffer of pending clients is full
341+
if ((_server.hasClientData() || _server.hasMaxPendingClients())
342+
&& timeSinceChange > HTTP_MAX_DATA_AVAILABLE_WAIT)
343+
DBGWS("webserver: closing since there's another connection to read from\n");
344+
else {
345+
if (timeSinceChange > HTTP_MAX_DATA_WAIT)
346+
DBGWS("webserver: closing after read timeout\n");
347+
else
348+
keepCurrentClient = true;
340349
}
341-
else
342-
DBGWS("webserver: closing after read timeout\n");
343350
callYield = true;
344351
}
345352
break;

Diff for: libraries/ESP8266WebServer/src/ESP8266WebServer.h

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ enum HTTPAuthMethod { BASIC_AUTH, DIGEST_AUTH };
5959
#endif
6060

6161
#define HTTP_MAX_DATA_WAIT 5000 //ms to wait for the client to send the request
62+
#define HTTP_MAX_DATA_AVAILABLE_WAIT 30 //ms to wait for the client to send the request when there is another client with data available
6263
#define HTTP_MAX_POST_WAIT 5000 //ms to wait for POST data to arrive
6364
#define HTTP_MAX_SEND_WAIT 5000 //ms to wait for data chunk to be ACKed
6465
#define HTTP_MAX_CLOSE_WAIT 2000 //ms to wait for the client to close the connection

Diff for: libraries/ESP8266WiFi/src/WiFiServer.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,25 @@ bool WiFiServer::hasClient() {
109109
return false;
110110
}
111111

112+
size_t WiFiServer::hasClientData() {
113+
ClientContext *next = _unclaimed;
114+
while (next) {
115+
size_t s = next->getSize();
116+
// return the amount of data available from the first connection that has any
117+
if (s) return s;
118+
next = next->next();
119+
}
120+
return 0;
121+
}
122+
123+
bool WiFiServer::hasMaxPendingClients() {
124+
#if TCP_LISTEN_BACKLOG
125+
return ((struct tcp_pcb_listen *)_listen_pcb)->accepts_pending >= MAX_PENDING_CLIENTS_PER_PORT;
126+
#else
127+
return false;
128+
#endif
129+
}
130+
112131
WiFiClient WiFiServer::available(byte* status) {
113132
(void) status;
114133
if (_unclaimed) {

Diff for: libraries/ESP8266WiFi/src/WiFiServer.h

+7
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ class WiFiServer : public Server {
8282
virtual ~WiFiServer() {}
8383
WiFiClient available(uint8_t* status = NULL);
8484
bool hasClient();
85+
// hasClientData():
86+
// returns the amount of data available from the first client
87+
// or 0 if there is none
88+
size_t hasClientData();
89+
// hasMaxPendingClients():
90+
// returns true if the queue of pending clients is full
91+
bool hasMaxPendingClients();
8592
void begin();
8693
void begin(uint16_t port);
8794
void begin(uint16_t port, uint8_t backlog);

0 commit comments

Comments
 (0)