Skip to content

Commit 3f485b6

Browse files
authored
Add files via upload
Changes to these files to fix the Heart Beat not working when client's wifi drops or it goes to to sleep causing the server to slow to a crawl. Heart Beat now works and client disconnects occur quickly with little disruption to other clients. Tested on ESP8266 with two WS servers and 5 clients. Clients can now reconnect after wifi drop. More debug statements added to trace the program flow.
1 parent 1789a18 commit 3f485b6

File tree

3 files changed

+30
-17
lines changed

3 files changed

+30
-17
lines changed

src/WebSockets.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -375,8 +375,7 @@ bool WebSockets::handleWebsocketWaitFor(WSclient_t * client, size_t size) {
375375
// timeout or error
376376
server->clientDisconnect(client, 1002);
377377
}
378-
},
379-
this, size, std::placeholders::_1, std::placeholders::_2));
378+
}, this, size, std::placeholders::_1, std::placeholders::_2));
380379
return false;
381380
}
382381

@@ -459,7 +458,12 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) {
459458
clientDisconnect(client, 1011);
460459
return;
461460
}
462-
readCb(client, payload, header->payloadLen, std::bind(&WebSockets::handleWebsocketPayloadCb, this, std::placeholders::_1, std::placeholders::_2, payload));
461+
//readCb(client, payload, header->payloadLen, std::bind(&WebSockets::handleWebsocketPayloadCb, this, std::placeholders::_1, std::placeholders::_2, payload));
462+
//todo this is because the original arguments don't match
463+
readCb(client, payload, header->payloadLen, [this, payload](WSclient_t * client, bool ok) {
464+
// Call the original method with the additional `payload` argument
465+
this->handleWebsocketPayloadCb(client, ok, payload);
466+
});
463467
} else {
464468
handleWebsocketPayloadCb(client, true, NULL);
465469
}
@@ -676,32 +680,32 @@ size_t WebSockets::write(WSclient_t * client, uint8_t * out, size_t n) {
676680
unsigned long t = millis();
677681
size_t len = 0;
678682
size_t total = 0;
679-
DEBUG_WEBSOCKETS("[write] n: %zu t: %lu\n", n, t);
683+
DEBUG_WEBSOCKETS("[write][%d] n: %zu t: %lu\n", client->num, n, t);
680684
while(n > 0) {
681685
if(client->tcp == NULL) {
682686
DEBUG_WEBSOCKETS("[write] tcp is null!\n");
683687
break;
684688
}
685689

686690
if(!client->tcp->connected()) {
687-
DEBUG_WEBSOCKETS("[write] not connected!\n");
691+
DEBUG_WEBSOCKETS("[write][%d] not connected!\n", client->num);
688692
break;
689693
}
690694

691695
if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) {
692-
DEBUG_WEBSOCKETS("[write] write TIMEOUT! %lu\n", (millis() - t));
696+
DEBUG_WEBSOCKETS("[write][%d] write TIMEOUT! %lu\n", client->num, (millis() - t));
693697
break;
694698
}
695699

696700
len = client->tcp->write((const uint8_t *)out, n);
697701
if(len) {
698-
t = millis();
702+
t = millis(); //why restart time?
699703
out += len;
700704
n -= len;
701705
total += len;
702-
// DEBUG_WEBSOCKETS("write %d left %d!\n", len, n);
706+
DEBUG_WEBSOCKETS("WS[write] normal sent: %d, left: %d, t: %lu\n", len, n, millis());
703707
} else {
704-
DEBUG_WEBSOCKETS("WS write %d failed left %d!\n", len, n);
708+
DEBUG_WEBSOCKETS("WS [write][%d] error sent: %d, left: %d, %lu\n", client->num, len, n, millis());
705709
}
706710
if(n > 0) {
707711
WEBSOCKETS_YIELD();
@@ -740,17 +744,18 @@ void WebSockets::enableHeartbeat(WSclient_t * client, uint32_t pingInterval, uin
740744
* @param client WSclient_t *
741745
*/
742746
void WebSockets::handleHBTimeout(WSclient_t * client) {
743-
if(client->pingInterval) { // if heartbeat is enabled
747+
if( (client->pingInterval) && (client->status == WSC_CONNECTED)) { // if heartbeat is enabled and connected
744748
uint32_t pi = millis() - client->lastPing;
745749

746750
if(client->pongReceived) {
747751
client->pongTimeoutCount = 0;
748752
} else {
749753
if(pi > client->pongTimeout) { // pong not received in time
750754
client->pongTimeoutCount++;
751-
client->lastPing = millis() - client->pingInterval - 500; // force ping on the next run
752755

753-
DEBUG_WEBSOCKETS("[HBtimeout] pong TIMEOUT! lp=%d millis=%lu pi=%d count=%d\n", client->lastPing, millis(), pi, client->pongTimeoutCount);
756+
DEBUG_WEBSOCKETS("[HBtimeout][%d] pong TIMEOUT! lp=%d millis=%lu pi=%d count=%d\n", client->num, client->lastPing, millis(), pi, client->pongTimeoutCount);
757+
758+
client->lastPing = millis() - client->pingInterval - 500; // give 500ms and force ping next run
754759

755760
if(client->disconnectTimeoutCount && client->pongTimeoutCount >= client->disconnectTimeoutCount) {
756761
DEBUG_WEBSOCKETS("[HBtimeout] count=%d, DISCONNECTING\n", client->pongTimeoutCount);

src/WebSockets.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
DEBUG_ESP_PORT.flush(); \
5151
}
5252
#else
53-
// #define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ )
53+
//#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) // Uncomment to debug
5454
#endif
5555
#endif
5656

src/WebSocketsServer.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,10 @@ WSclient_t * WebSocketsServerCore::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclien
451451
return client;
452452
}
453453
#endif
454+
DEBUG_WEBSOCKETS("[WS-Server][newclient][%d] is in use\n", client->num);
454455
} else {
455456
// state is not connected or tcp connection is lost
457+
DEBUG_WEBSOCKETS("[WS-Server][newclient][%d] available for connection\n", client->num);
456458
client->tcp = TCPclient;
457459

458460
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
@@ -491,9 +493,10 @@ WSclient_t * WebSocketsServerCore::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclien
491493

492494
client->pingInterval = _pingInterval;
493495
client->pongTimeout = _pongTimeout;
496+
client->pongTimeoutCount = 0; //gw addition reset to zero for new client
494497
client->disconnectTimeoutCount = _disconnectTimeoutCount;
495498
client->lastPing = millis();
496-
client->pongReceived = false;
499+
client->pongReceived = true; //gw set true - no spurious timeout before first ping sent following WSC_CONNECTED
497500

498501
return client;
499502
break;
@@ -599,6 +602,8 @@ void WebSocketsServerCore::clientDisconnect(WSclient_t * client) {
599602
DEBUG_WEBSOCKETS("[WS-Server][%d] client disconnected.\n", client->num);
600603

601604
runCbEvent(client->num, WStype_DISCONNECTED, NULL, 0);
605+
606+
DEBUG_WEBSOCKETS("WS-Server][%d], pongTimeoutCount %d, (should be zero)\n", client->num, client->pongTimeoutCount); //todo this is for testing
602607
}
603608

604609
/**
@@ -657,6 +662,9 @@ WSclient_t * WebSocketsServerCore::handleNewClient(WEBSOCKETS_NETWORK_CLASS * tc
657662
return nullptr;
658663
}
659664

665+
//test to see if ping timeout values are correct todo remove
666+
DEBUG_WEBSOCKETS("[WS-Client] [handleNewClients] [%d] PongTimeoutCount %d, should be zero for new client\n", client->num, client->pongTimeoutCount);
667+
660668
WEBSOCKETS_YIELD();
661669

662670
return client;
@@ -882,8 +890,8 @@ void WebSocketsServerCore::handleHeader(WSclient_t * client, String * headerLine
882890

883891
headerDone(client);
884892

885-
// send ping
886-
WebSockets::sendFrame(client, WSop_ping);
893+
// Send HeartBeat Ping if enabled
894+
handleHBPing(client);
887895

888896
runCbEvent(client->num, WStype_CONNECTED, (uint8_t *)client->cUrl.c_str(), client->cUrl.length());
889897

@@ -897,7 +905,7 @@ void WebSocketsServerCore::handleHeader(WSclient_t * client, String * headerLine
897905
* send heartbeat ping to server in set intervals
898906
*/
899907
void WebSocketsServerCore::handleHBPing(WSclient_t * client) {
900-
if(client->pingInterval == 0)
908+
if( (client->pingInterval == 0) || client->status != WSC_CONNECTED)
901909
return;
902910
uint32_t pi = millis() - client->lastPing;
903911
if(pi > client->pingInterval) {

0 commit comments

Comments
 (0)