Skip to content
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

Modifications to solve Issue #922 #940

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
29 changes: 17 additions & 12 deletions src/WebSockets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,7 @@ bool WebSockets::handleWebsocketWaitFor(WSclient_t * client, size_t size) {
// timeout or error
server->clientDisconnect(client, 1002);
}
},
this, size, std::placeholders::_1, std::placeholders::_2));
}, this, size, std::placeholders::_1, std::placeholders::_2));
return false;
}

Expand Down Expand Up @@ -459,7 +458,12 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) {
clientDisconnect(client, 1011);
return;
}
readCb(client, payload, header->payloadLen, std::bind(&WebSockets::handleWebsocketPayloadCb, this, std::placeholders::_1, std::placeholders::_2, payload));
//readCb(client, payload, header->payloadLen, std::bind(&WebSockets::handleWebsocketPayloadCb, this, std::placeholders::_1, std::placeholders::_2, payload));
//todo this is because the original arguments don't match
readCb(client, payload, header->payloadLen, [this, payload](WSclient_t * client, bool ok) {
// Call the original method with the additional `payload` argument
this->handleWebsocketPayloadCb(client, ok, payload);
});
} else {
handleWebsocketPayloadCb(client, true, NULL);
}
Expand Down Expand Up @@ -676,32 +680,32 @@ size_t WebSockets::write(WSclient_t * client, uint8_t * out, size_t n) {
unsigned long t = millis();
size_t len = 0;
size_t total = 0;
DEBUG_WEBSOCKETS("[write] n: %zu t: %lu\n", n, t);
DEBUG_WEBSOCKETS("[write][%d] n: %zu t: %lu\n", client->num, n, t);
while(n > 0) {
if(client->tcp == NULL) {
DEBUG_WEBSOCKETS("[write] tcp is null!\n");
break;
}

if(!client->tcp->connected()) {
DEBUG_WEBSOCKETS("[write] not connected!\n");
DEBUG_WEBSOCKETS("[write][%d] not connected!\n", client->num);
break;
}

if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) {
DEBUG_WEBSOCKETS("[write] write TIMEOUT! %lu\n", (millis() - t));
DEBUG_WEBSOCKETS("[write][%d] write TIMEOUT! %lu\n", client->num, (millis() - t));
break;
}

len = client->tcp->write((const uint8_t *)out, n);
if(len) {
t = millis();
t = millis(); //why restart time?
out += len;
n -= len;
total += len;
// DEBUG_WEBSOCKETS("write %d left %d!\n", len, n);
DEBUG_WEBSOCKETS("WS[write] normal sent: %d, left: %d, t: %lu\n", len, n, millis());
} else {
DEBUG_WEBSOCKETS("WS write %d failed left %d!\n", len, n);
DEBUG_WEBSOCKETS("WS [write][%d] error sent: %d, left: %d, %lu\n", client->num, len, n, millis());
}
if(n > 0) {
WEBSOCKETS_YIELD();
Expand Down Expand Up @@ -740,17 +744,18 @@ void WebSockets::enableHeartbeat(WSclient_t * client, uint32_t pingInterval, uin
* @param client WSclient_t *
*/
void WebSockets::handleHBTimeout(WSclient_t * client) {
if(client->pingInterval) { // if heartbeat is enabled
if( (client->pingInterval) && (client->status == WSC_CONNECTED)) { // if heartbeat is enabled and connected
uint32_t pi = millis() - client->lastPing;

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

DEBUG_WEBSOCKETS("[HBtimeout] pong TIMEOUT! lp=%d millis=%lu pi=%d count=%d\n", client->lastPing, millis(), pi, client->pongTimeoutCount);
DEBUG_WEBSOCKETS("[HBtimeout][%d] pong TIMEOUT! lp=%d millis=%lu pi=%d count=%d\n", client->num, client->lastPing, millis(), pi, client->pongTimeoutCount);

client->lastPing = millis() - client->pingInterval - 500; //force send ping next loop, next time out in client->pongTimeout

if(client->disconnectTimeoutCount && client->pongTimeoutCount >= client->disconnectTimeoutCount) {
DEBUG_WEBSOCKETS("[HBtimeout] count=%d, DISCONNECTING\n", client->pongTimeoutCount);
Expand Down
2 changes: 1 addition & 1 deletion src/WebSockets.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
DEBUG_ESP_PORT.flush(); \
}
#else
// #define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ )
//#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) // Uncomment to debug
#endif
#endif

Expand Down
16 changes: 12 additions & 4 deletions src/WebSocketsServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,10 @@ WSclient_t * WebSocketsServerCore::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclien
return client;
}
#endif
DEBUG_WEBSOCKETS("[WS-Server][newclient][%d] is in use\n", client->num);
} else {
// state is not connected or tcp connection is lost
DEBUG_WEBSOCKETS("[WS-Server][newclient][%d] available for connection\n", client->num);
client->tcp = TCPclient;

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

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

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

runCbEvent(client->num, WStype_DISCONNECTED, NULL, 0);

DEBUG_WEBSOCKETS("WS-Server][%d], pongTimeoutCount %d, (should be zero)\n", client->num, client->pongTimeoutCount); //todo this is for testing
}

/**
Expand Down Expand Up @@ -657,6 +662,9 @@ WSclient_t * WebSocketsServerCore::handleNewClient(WEBSOCKETS_NETWORK_CLASS * tc
return nullptr;
}

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

WEBSOCKETS_YIELD();

return client;
Expand Down Expand Up @@ -882,8 +890,8 @@ void WebSocketsServerCore::handleHeader(WSclient_t * client, String * headerLine

headerDone(client);

// send ping
WebSockets::sendFrame(client, WSop_ping);
// Send HeartBeat Ping if enabled
handleHBPing(client);

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

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