handle cases when not all data can be written to TCP stack #187

This commit is contained in:
Links
2017-04-09 17:58:23 +02:00
parent 81e567b248
commit adb52b11e9
4 changed files with 61 additions and 6 deletions

View File

@ -233,18 +233,18 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay
// header has be added to payload // header has be added to payload
// payload is forced to reserved 14 Byte but we may not need all based on the length and mask settings // payload is forced to reserved 14 Byte but we may not need all based on the length and mask settings
// offset in payload is calculatetd 14 - headerSize // offset in payload is calculatetd 14 - headerSize
if(client->tcp->write(&payloadPtr[(WEBSOCKETS_MAX_HEADER_SIZE - headerSize)], (length + headerSize)) != (length + headerSize)) { if(write(client, &payloadPtr[(WEBSOCKETS_MAX_HEADER_SIZE - headerSize)], (length + headerSize)) != (length + headerSize)) {
ret = false; ret = false;
} }
} else { } else {
// send header // send header
if(client->tcp->write(&buffer[0], headerSize) != headerSize) { if(write(client, &buffer[0], headerSize) != headerSize) {
ret = false; ret = false;
} }
if(payloadPtr && length > 0) { if(payloadPtr && length > 0) {
// send payload // send payload
if(client->tcp->write(&payloadPtr[0], length) != length) { if(write(client, &payloadPtr[0], length) != length) {
ret = false; ret = false;
} }
} }
@ -593,3 +593,56 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait
#endif #endif
return true; return true;
} }
/**
* write x byte to tcp or get timeout
* @param client WSclient_t *
* @param out uint8_t * data buffer
* @param n size_t byte count
* @return true if ok
*/
size_t WebSockets::write(WSclient_t * client, uint8_t *out, size_t n) {
if(out == NULL) return 0;
if(client == NULL) return 0;
unsigned long t = millis();
size_t len = 0;
size_t total = 0;
DEBUG_WEBSOCKETS("[size_t] n: %d t: %d\n", 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");
break;
}
if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) {
DEBUG_WEBSOCKETS("[write] write TIMEOUT! %d\n", (millis() - t));
break;
}
len = client->tcp->write(out, n);
if(len) {
t = millis();
out += len;
n -= len;
total += len;
//DEBUG_WEBSOCKETS("write %d left %d!\n", len, n);
} else {
//DEBUG_WEBSOCKETS("write %d failed left %d!\n", len, n);
}
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
delay(0);
#endif
}
return total;
}
size_t WebSockets::write(WSclient_t * client, const char *out) {
if(client == NULL) return 0;
if(out == NULL) return 0;
return write(client, (uint8_t*)out, strlen(out));
}

View File

@ -265,6 +265,8 @@ class WebSockets {
String base64_encode(uint8_t * data, size_t length); String base64_encode(uint8_t * data, size_t length);
bool readCb(WSclient_t * client, uint8_t *out, size_t n, WSreadWaitCb cb); bool readCb(WSclient_t * client, uint8_t *out, size_t n, WSreadWaitCb cb);
size_t write(WSclient_t * client, uint8_t *out, size_t n);
size_t write(WSclient_t * client, const char *out);
}; };

View File

@ -482,7 +482,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
handshake += NEW_LINE; handshake += NEW_LINE;
DEBUG_WEBSOCKETS("[WS-Client][sendHeader] handshake %s", (uint8_t*)handshake.c_str()); DEBUG_WEBSOCKETS("[WS-Client][sendHeader] handshake %s", (uint8_t*)handshake.c_str());
client->tcp->write((uint8_t*)handshake.c_str(), handshake.length()); write(client, (uint8_t*)handshake.c_str(), handshake.length());
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine))); client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine)));
@ -607,7 +607,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
sendHeader(client); sendHeader(client);
} else { } else {
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n"); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n");
client->tcp->write("This is a webSocket client!"); write(client, "This is a webSocket client!");
clientDisconnect(client); clientDisconnect(client);
} }
} }

View File

@ -809,7 +809,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] handshake %s", client->num, (uint8_t*)handshake.c_str()); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] handshake %s", client->num, (uint8_t*)handshake.c_str());
client->tcp->write((uint8_t*)handshake.c_str(), handshake.length()); write(client, (uint8_t*)handshake.c_str(), handshake.length());
headerDone(client); headerDone(client);