Skip to content

ESP8266WebServer - Drop inactive connection when another is waiting to improve page load time #8216

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 27, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/esp8266wifi/server-class.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ Other Function Calls
.. code:: cpp

bool hasClient ()
size_t hasClientData ()
bool hasMaxPendingClients ()
bool getNoDelay ()
virtual size_t write (const uint8_t *buf, size_t size)
uint8_t status ()
Expand Down
15 changes: 11 additions & 4 deletions libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,11 +335,18 @@ void ESP8266WebServerTemplate<ServerType>::handleClient() {
} // switch _parseRequest()
} else {
// !_currentClient.available(): waiting for more data
if (millis() - _statusChange <= HTTP_MAX_DATA_WAIT) {
keepCurrentClient = true;
unsigned long timeSinceChange = millis() - _statusChange;
// Use faster connection drop timeout if any other client has data
// or the buffer of pending clients is full
if ((_server.hasClientData() || _server.hasMaxPendingClients())
&& timeSinceChange > HTTP_MAX_DATA_AVAILABLE_WAIT)
DBGWS("webserver: closing since there's another connection to read from\n");
else {
if (timeSinceChange > HTTP_MAX_DATA_WAIT)
DBGWS("webserver: closing after read timeout\n");
else
keepCurrentClient = true;
}
else
DBGWS("webserver: closing after read timeout\n");
callYield = true;
}
break;
Expand Down
1 change: 1 addition & 0 deletions libraries/ESP8266WebServer/src/ESP8266WebServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ enum HTTPAuthMethod { BASIC_AUTH, DIGEST_AUTH };
#endif

#define HTTP_MAX_DATA_WAIT 5000 //ms to wait for the client to send the request
#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
#define HTTP_MAX_POST_WAIT 5000 //ms to wait for POST data to arrive
#define HTTP_MAX_SEND_WAIT 5000 //ms to wait for data chunk to be ACKed
#define HTTP_MAX_CLOSE_WAIT 2000 //ms to wait for the client to close the connection
Expand Down
19 changes: 19 additions & 0 deletions libraries/ESP8266WiFi/src/WiFiServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,25 @@ bool WiFiServer::hasClient() {
return false;
}

size_t WiFiServer::hasClientData() {
ClientContext *next = _unclaimed;
while (next) {
size_t s = next->getSize();
// return the amount of data available from the first connection that has any
if (s) return s;
next = next->next();
}
return 0;
}

bool WiFiServer::hasMaxPendingClients() {
#if TCP_LISTEN_BACKLOG
return ((struct tcp_pcb_listen *)_listen_pcb)->accepts_pending >= MAX_PENDING_CLIENTS_PER_PORT;
#else
return false;
#endif
}

WiFiClient WiFiServer::available(byte* status) {
(void) status;
if (_unclaimed) {
Expand Down
7 changes: 7 additions & 0 deletions libraries/ESP8266WiFi/src/WiFiServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ class WiFiServer : public Server {
virtual ~WiFiServer() {}
WiFiClient available(uint8_t* status = NULL);
bool hasClient();
// hasClientData():
// returns the amount of data available from the first client
// or 0 if there is none
size_t hasClientData();
// hasMaxPendingClients():
// returns true if the queue of pending clients is full
bool hasMaxPendingClients();
void begin();
void begin(uint16_t port);
void begin(uint16_t port, uint8_t backlog);
Expand Down