add handling for Socket.IO V3 connection

This commit is contained in:
Links
2020-11-21 16:19:59 +01:00
parent 9470961d85
commit c5900db636
2 changed files with 45 additions and 9 deletions

View File

@ -215,6 +215,7 @@
typedef enum { typedef enum {
WSC_NOT_CONNECTED, WSC_NOT_CONNECTED,
WSC_HEADER, WSC_HEADER,
WSC_BODY,
WSC_CONNECTED WSC_CONNECTED
} WSclientsStatus_t; } WSclientsStatus_t;

View File

@ -505,7 +505,8 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) {
client->cIsWebsocket = false; client->cIsWebsocket = false;
client->cSessionId = ""; client->cSessionId = "";
client->status = WSC_NOT_CONNECTED; client->status = WSC_NOT_CONNECTED;
_lastConnectionFail = millis();
DEBUG_WEBSOCKETS("[WS-Client] client disconnected.\n"); DEBUG_WEBSOCKETS("[WS-Client] client disconnected.\n");
if(event) { if(event) {
@ -548,12 +549,13 @@ bool WebSocketsClient::clientIsConnected(WSclient_t * client) {
* Handel incomming data from Client * Handel incomming data from Client
*/ */
void WebSocketsClient::handleClientData(void) { void WebSocketsClient::handleClientData(void) {
if(_client.status == WSC_HEADER && _lastHeaderSent + WEBSOCKETS_TCP_TIMEOUT < millis()) { if((_client.status == WSC_HEADER || _client.status == WSC_BODY) && _lastHeaderSent + WEBSOCKETS_TCP_TIMEOUT < millis()) {
DEBUG_WEBSOCKETS("[WS-Client][handleClientData] header response timeout.. disconnecting!\n"); DEBUG_WEBSOCKETS("[WS-Client][handleClientData] header response timeout.. disconnecting!\n");
clientDisconnect(&_client); clientDisconnect(&_client);
WEBSOCKETS_YIELD(); WEBSOCKETS_YIELD();
return; return;
} }
int len = _client.tcp->available(); int len = _client.tcp->available();
if(len > 0) { if(len > 0) {
switch(_client.status) { switch(_client.status) {
@ -561,6 +563,12 @@ void WebSocketsClient::handleClientData(void) {
String headerLine = _client.tcp->readStringUntil('\n'); String headerLine = _client.tcp->readStringUntil('\n');
handleHeader(&_client, &headerLine); handleHeader(&_client, &headerLine);
} break; } break;
case WSC_BODY: {
char buf[256] = { 0 };
_client.tcp->readBytes(&buf[0], std::min((size_t)len, sizeof(buf)));
String bodyLine = buf;
handleHeader(&_client, &bodyLine);
} break;
case WSC_CONNECTED: case WSC_CONNECTED:
WebSockets::handleWebsocket(&_client); WebSockets::handleWebsocket(&_client);
break; break;
@ -672,6 +680,22 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
headerLine->trim(); // remove \r headerLine->trim(); // remove \r
// this code handels the http body for Socket.IO V3 requests
if(headerLine->length() > 0 && client->isSocketIO && client->status == WSC_BODY && client->cSessionId.length() == 0) {
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] socket.io json: %s\n", headerLine->c_str());
String sid_begin = WEBSOCKETS_STRING("\"sid\":\"");
if(headerLine->indexOf(sid_begin) > -1) {
int start = headerLine->indexOf(sid_begin) + sid_begin.length();
int end = headerLine->indexOf('"', start);
client->cSessionId = headerLine->substring(start, end);
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cSessionId: %s\n", client->cSessionId.c_str());
// Trigger websocket connection code path
*headerLine = "";
}
}
// headle HTTP header
if(headerLine->length() > 0) { if(headerLine->length() > 0) {
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str()); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str());
@ -736,6 +760,14 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cVersion: %d\n", client->cVersion); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cVersion: %d\n", client->cVersion);
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cSessionId: %s\n", client->cSessionId.c_str()); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cSessionId: %s\n", client->cSessionId.c_str());
if(client->isSocketIO && client->cSessionId.length() == 0 && clientIsConnected(client)) {
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] still missing cSessionId try socket.io V3\n");
client->status = WSC_BODY;
return;
} else {
client->status = WSC_HEADER;
}
bool ok = (client->cIsUpgrade && client->cIsWebsocket); bool ok = (client->cIsUpgrade && client->cIsWebsocket);
if(ok) { if(ok) {
@ -777,15 +809,18 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
runCbEvent(WStype_CONNECTED, (uint8_t *)client->cUrl.c_str(), client->cUrl.length()); runCbEvent(WStype_CONNECTED, (uint8_t *)client->cUrl.c_str(), client->cUrl.length());
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) #if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
} else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) { } else if(client->isSocketIO) {
if(_client.tcp->available()) { if(client->cSessionId.length() > 0) {
// read not needed data DEBUG_WEBSOCKETS("[WS-Client][handleHeader] found cSessionId\n");
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] still data in buffer (%d), clean up.\n", _client.tcp->available()); if(clientIsConnected(client) && _client.tcp->available()) {
while(_client.tcp->available() > 0) { // read not needed data
_client.tcp->read(); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] still data in buffer (%d), clean up.\n", _client.tcp->available());
while(_client.tcp->available() > 0) {
_client.tcp->read();
}
} }
sendHeader(client);
} }
sendHeader(client);
#endif #endif
} else { } else {
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n"); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n");