diff --git a/examples/WebSocketClientEthernet2/WebSocketClient.ino b/examples/WebSocketClientEthernet2/WebSocketClient.ino new file mode 100644 index 0000000..477aa98 --- /dev/null +++ b/examples/WebSocketClientEthernet2/WebSocketClient.ino @@ -0,0 +1,80 @@ +/* + * WebSocketClient.ino + * + * Created on: 27.05.2018 + * + */ +#include +#include +#include + +WebSocketsClient webSocket; + +byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF}; +IPAddress ip(192, 168, 0, 110); +#define USE_SERIAL Serial + +void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) { + + + switch(type) { + case WStype_DISCONNECTED: + //USE_SERIAL.printf("[WSc] Disconnected!\n"); + USE_SERIAL << "[WSc] Disconnected!" << endl; + break; + case WStype_CONNECTED: + { + //USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); + USE_SERIAL << "[WSc] Connected to url: " << (char*)payload << endl; + // send message to server when Connected + webSocket.sendTXT("Connected"); + } + break; + case WStype_TEXT: + //USE_SERIAL.printf("[WSc] get text: %s\n", payload); + USE_SERIAL << "[WSc] get text: " << (char*)payload << endl; + + // send message to server + // webSocket.sendTXT("message here"); + break; + case WStype_BIN: + //USE_SERIAL.printf("[WSc] get binary lenght: %u\n", lenght); + USE_SERIAL << "[WSc] get binary lenght: " << lenght << endl; + //hexdump(payload, lenght); + + // send data to server + // webSocket.sendBIN(payload, lenght); + break; + } + +} + +void setup() { + // USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + //USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL << "[SETUP] BOOT WAIT " << t << "..." << endl; + USE_SERIAL.flush(); + delay(1000); + } + + Ethernet.begin(mac,ip); + USE_SERIAL << Ethernet.localIP() << endl; + + + + //webSocket.begin("wss://echo.websocket.org", 443); + webSocket.begin("ws://echo.websocket.org", 80); + webSocket.onEvent(webSocketEvent); + +} + +void loop() { + webSocket.loop(); +} \ No newline at end of file diff --git a/examples/WebSocketServer/WebSocketServer.ino b/examples/WebSocketServer/WebSocketServer.ino index 795d9a6..3ac7216 100644 --- a/examples/WebSocketServer/WebSocketServer.ino +++ b/examples/WebSocketServer/WebSocketServer.ino @@ -1,86 +1,60 @@ -/* - * WebSocketServer.ino - * - * Created on: 22.05.2015 - * - */ - -#include - -#include -#include +#include #include -#include +#include -ESP8266WiFiMulti WiFiMulti; +#define USE_SERIAL Serial +byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF}; +IPAddress ip(192, 168, 0, 110); -WebSocketsServer webSocket = WebSocketsServer(81); - -#define USE_SERIAL Serial1 +WebSocketsServer webSocket = WebSocketsServer(8081); void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) { - switch(type) { - case WStype_DISCONNECTED: - USE_SERIAL.printf("[%u] Disconnected!\n", num); - break; - case WStype_CONNECTED: - { - IPAddress ip = webSocket.remoteIP(num); - USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); - - // send message to client - webSocket.sendTXT(num, "Connected"); - } - break; - case WStype_TEXT: - USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); - - // send message to client - // webSocket.sendTXT(num, "message here"); - - // send data to all connected clients - // webSocket.broadcastTXT("message here"); - break; - case WStype_BIN: - USE_SERIAL.printf("[%u] get binary lenght: %u\n", num, lenght); - hexdump(payload, lenght); - - // send message to client - // webSocket.sendBIN(num, payload, lenght); - break; - } - + switch (type) { + case WStype_DISCONNECTED: + USE_SERIAL << num << " Disconnected!" << endl; + break; + case WStype_CONNECTED: + { + //IPAddress ip = webSocket.remoteIP(num); + USE_SERIAL << num << " Connected url: " << (char*)payload << endl; + // send message to client + webSocket.sendTXT(num, "Connected"); + } + break; + case WStype_TEXT: + USE_SERIAL << num << " get Text: " << (char*)payload << endl; + + // send message to client + webSocket.sendTXT(num, "message here"); + + // send data to all connected clients + webSocket.broadcastTXT("broadcast message here"); + break; + case WStype_BIN: + USE_SERIAL << num << " get binary lenght: "; + + // send message to client + webSocket.sendBIN(num, payload, lenght); + break; + } } void setup() { - // USE_SERIAL.begin(921600); - USE_SERIAL.begin(115200); - - //Serial.setDebugOutput(true); - USE_SERIAL.setDebugOutput(true); - - USE_SERIAL.println(); - USE_SERIAL.println(); - USE_SERIAL.println(); - - for(uint8_t t = 4; t > 0; t--) { - USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); - USE_SERIAL.flush(); - delay(1000); - } - - WiFiMulti.addAP("SSID", "passpasspass"); - - while(WiFiMulti.run() != WL_CONNECTED) { - delay(100); - } - - webSocket.begin(); - webSocket.onEvent(webSocketEvent); + USE_SERIAL.begin(115200); + Ethernet.begin(mac, ip); + USE_SERIAL.println("\n\n"); + USE_SERIAL.println(Ethernet.localIP()); + + for (uint8_t t = 4; t > 0; t--) { + USE_SERIAL.flush(); + delay(1000); + } + + webSocket.begin(); + webSocket.onEvent(webSocketEvent); } void loop() { - webSocket.loop(); + webSocket.loop(); } - diff --git a/examples/WebSocketServer/WebSocketServer_ethernetShield2.ino b/examples/WebSocketServer/WebSocketServer_ethernetShield2.ino new file mode 100644 index 0000000..9cea53a --- /dev/null +++ b/examples/WebSocketServer/WebSocketServer_ethernetShield2.ino @@ -0,0 +1,82 @@ +#include +#include +#include +#include +/////////#include //downloaded from https://github.com/Yveaux/Arduino_HexDump + +#include +//#include + +#include + +byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF}; +IPAddress ip(192, 168, 0, 110); + +WebSocketsServer webSocket = WebSocketsServer(8081); + +#define USE_SERIAL Serial + +void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) { + + switch(type) { + case WStype_DISCONNECTED: + //USE_SERIAL.printf("[%u] Disconnected!\n", num); + USE_SERIAL << num << " Disconnected!" << endl; + break; + case WStype_CONNECTED: + { + //IPAddress ip = webSocket.remoteIP(num); + //USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); + USE_SERIAL << num << " Connected url: " << int(payload) << endl; + // send message to client + webSocket.sendTXT(num, "Connected"); + } + break; + case WStype_TEXT: + //USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); + USE_SERIAL << num << " get Text: " << int(payload) << endl; + + // send message to client + webSocket.sendTXT(num, "message here"); + + // send data to all connected clients + webSocket.broadcastTXT("message here"); + break; + case WStype_BIN: + //USE_SERIAL.printf("[%u] get binary lenght: %u\n", num, lenght); + USE_SERIAL << num <<" get binary lenght: " << lenght << endl; + ///////////hexdump(payload, lenght); + + // send message to client + webSocket.sendBIN(num, payload, lenght); + break; + } + +} + +void setup() { + // USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + Ethernet.begin(mac, ip); + +// USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + //USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + + webSocket.begin(); + webSocket.onEvent(webSocketEvent); +} + +void loop() { + webSocket.loop(); +} diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 4ec9a1f..2b38aaf 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -55,9 +55,12 @@ extern "C" { * @param reason * @param reasonLen */ -void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * reason, size_t reasonLen) { - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] clientDisconnect code: %u\n", client->num, code); - if(client->status == WSC_CONNECTED && code) { +void WebSockets::clientDisconnect(WSclient_t & client, uint16_t code, char * reason, size_t reasonLen) { + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINT("][handleWebsocket] clientDisconnect code: "); + WS_PRINTLN(code); + if(client.status == WSC_CONNECTED && code) { if(reason) { sendFrame(client, WSop_close, (uint8_t *) reason, reasonLen); } else { @@ -80,23 +83,48 @@ void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * rea * @param fin bool can be used to send data in more then one frame (set fin on the last frame) * @param headerToPayload bool set true if the payload has reserved 14 Byte at the beginning to dynamically add the Header (payload neet to be in RAM!) */ -void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool mask, bool fin, bool headerToPayload) { - - if(client->tcp && !client->tcp->connected()) { - DEBUG_WEBSOCKETS("[WS][%d][sendFrame] not Connected!?\n", client->num); +void WebSockets::sendFrame(WSclient_t & client, WSopcode_t opcode, uint8_t * payload, size_t length, bool mask, bool fin, bool headerToPayload) { + if(client.tcp && !client.tcp.connected()) { +#ifdef WS_DEBUG + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINTLN("][sendFrame] not Connected!?"); +#endif return; } - if(client->status != WSC_CONNECTED) { - DEBUG_WEBSOCKETS("[WS][%d][sendFrame] not in WSC_CONNECTED state!?\n", client->num); + if(client.status != WSC_CONNECTED) { +#ifdef WS_DEBUG + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINTLN("][sendFrame] not in WSC_CONNECTED state!?"); +#endif return; } - - DEBUG_WEBSOCKETS("[WS][%d][sendFrame] ------- send massage frame -------\n", client->num); - DEBUG_WEBSOCKETS("[WS][%d][sendFrame] fin: %u opCode: %u mask: %u length: %u headerToPayload: %u\n", client->num, fin, opcode, mask, length, headerToPayload); - +#ifdef WS_DEBUG + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINTLN("][sendFrame] ------- send message frame -------"); + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINT("][sendFrame] fin: "); + WS_PRINT(fin); + WS_PRINT(" opCode: "); + WS_PRINT(opcode); + WS_PRINT(" mask: "); + WS_PRINT(mask); + WS_PRINT(" length: "); + WS_PRINT(length); + WS_PRINT(" headerToPayload: "); + WS_PRINTLN(headerToPayload); +#endif if(opcode == WSop_text) { - DEBUG_WEBSOCKETS("[WS][%d][sendFrame] text: %s\n", client->num, (payload + (headerToPayload ? 14 : 0))); +#ifdef WS_DEBUG + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINT("][sendFrame] text: "); + WS_PRINTLN(reinterpret_cast(payload + (headerToPayload ? 14 : 0)));//<<<------------------------------------------------ +#endif } uint8_t maskKey[4] = { 0x00, 0x00, 0x00, 0x00 }; @@ -125,7 +153,11 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay // only for ESP since AVR has less HEAP // try to send data in one TCP package (only if some free Heap is there) if(!headerToPayload && ((length > 0) && (length < 1400)) && (ESP.getFreeHeap() > 6000)) { - DEBUG_WEBSOCKETS("[WS][%d][sendFrame] pack to one TCP package...\n", client->num); +#ifdef WS_DEBUG + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINTLN("][sendFrame] pack to one TCP package..."); +#endif uint8_t * dataPtr = (uint8_t *) malloc(length + WEBSOCKETS_MAX_HEADER_SIZE); if(dataPtr) { memcpy((dataPtr + WEBSOCKETS_MAX_HEADER_SIZE), payload, length); @@ -216,18 +248,17 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay // 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 // offset in payload is calculatetd 14 - headerSize - client->tcp->write(&payloadPtr[(WEBSOCKETS_MAX_HEADER_SIZE - headerSize)], (length + headerSize)); + client.tcp.write(&payloadPtr[(WEBSOCKETS_MAX_HEADER_SIZE - headerSize)], (length + headerSize)); } else { // send header - client->tcp->write(&buffer[0], headerSize); + client.tcp.write(&buffer[0], headerSize); if(payloadPtr && length > 0) { // send payload - client->tcp->write(&payloadPtr[0], length); + client.tcp.write(&payloadPtr[0], length); } } - DEBUG_WEBSOCKETS("[WS][%d][sendFrame] sending Frame Done (%uus).\n", client->num, (micros() - start)); #ifdef WEBSOCKETS_USE_BIG_MEM if(useInternBuffer && payloadPtr) { @@ -241,8 +272,7 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay * handle the WebSocket stream * @param client WSclient_t * ptr to the client struct */ -void WebSockets::handleWebsocket(WSclient_t * client) { - +void WebSockets::handleWebsocket(WSclient_t & client) { uint8_t buffer[8] = { 0 }; bool fin; @@ -256,9 +286,11 @@ void WebSockets::handleWebsocket(WSclient_t * client) { uint8_t maskKey[4]; uint8_t * payload = NULL; - - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] ------- read massage frame -------\n", client->num); - +#ifdef WS_DEBUG + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINTLN("][handleWebsocket] ------- read massage frame -------"); +#endif if(!readWait(client, buffer, 2)) { //timeout clientDisconnect(client, 1002); @@ -297,13 +329,35 @@ void WebSockets::handleWebsocket(WSclient_t * client) { payloadLen = buffer[4] << 24 | buffer[5] << 16 | buffer[6] << 8 | buffer[7]; } } - - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] fin: %u rsv1: %u rsv2: %u rsv3 %u opCode: %u\n", client->num, fin, rsv1, rsv2, rsv3, opCode); - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] mask: %u payloadLen: %u\n", client->num, mask, payloadLen); - +#ifdef WS_DEBUG + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINT("][handleWebsocket] fin: "); + WS_PRINT(fin); + WS_PRINT(" rsv1: "); + WS_PRINT(rsv1); + WS_PRINT(" rsv2: "); + WS_PRINT(rsv2); + WS_PRINT(" rsv3: "); + WS_PRINT(rsv3); + WS_PRINT(" opCode: "); + WS_PRINTLN(opCode); + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINT("][handleWebsocket] mask: "); + WS_PRINT(mask); + WS_PRINT(" payloadLen: "); + WS_PRINTLN(payloadLen); +#endif if(payloadLen > WEBSOCKETS_MAX_DATA_SIZE) { - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] payload to big! (%u)\n", client->num, payloadLen); +#ifdef WS_DEBUG + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINT("][handleWebsocket] payload to big! ("); + WS_PRINT(payloadLen); + WS_PRINTLN(")"); clientDisconnect(client, 1009); +#endif return; } @@ -320,13 +374,23 @@ void WebSockets::handleWebsocket(WSclient_t * client) { payload = (uint8_t *) malloc(payloadLen + 1); if(!payload) { - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] to less memory to handle payload %d!\n", client->num, payloadLen); +#ifdef WS_DEBUG + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINT("][handleWebsocket] to less memory to handle payload "); + WS_PRINT(payloadLen); + WS_PRINTLN("!"); +#endif clientDisconnect(client, 1011); return; } if(!readWait(client, payload, payloadLen)) { - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] missing data!\n", client->num); +#ifdef WS_DEBUG + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINTLN("][handleWebsocket] missing data!"); +#endif free(payload); clientDisconnect(client, 1002); return; @@ -344,17 +408,28 @@ void WebSockets::handleWebsocket(WSclient_t * client) { switch(opCode) { case WSop_text: - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] text: %s\n", client->num, payload); +#ifdef WS_DEBUG + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINT("][handleWebsocket] text: "); + WS_PRINTLN(reinterpret_cast(payload));//<<<------------------------------------------------ +#endif // no break here! case WSop_binary: - messageRecived(client, opCode, payload, payloadLen); + messageReceived(client, opCode, payload, payloadLen); break; case WSop_ping: // send pong back sendFrame(client, WSop_pong, payload, payloadLen); break; case WSop_pong: - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload); +#ifdef WS_DEBUG + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINT("][handleWebsocket] get pong ("); + WS_PRINT(reinterpret_cast(payload));//<<<------------------------------------------------ + WS_PRINTLN(")"); +#endif break; case WSop_close: { @@ -362,12 +437,22 @@ void WebSockets::handleWebsocket(WSclient_t * client) { if(payloadLen >= 2) { reasonCode = payload[0] << 8 | payload[1]; } - - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get ask for close. Code: %d", client->num, reasonCode); +#ifdef WS_DEBUG + WS_PRINT("[WS]["); + WS_PRINT(client.num); + WS_PRINT("][handleWebsocket] get ask for close. Code: "); + WS_PRINTLN(reasonCode); +#endif if(payloadLen > 2) { - DEBUG_WEBSOCKETS(" (%s)\n", (payload+2)); +#ifdef WS_DEBUG + WS_PRINT(" ("); + WS_PRINT(reinterpret_cast(payload+2));//<<<------------------------------------------------ + WS_PRINTLN(")"); +#endif } else { - DEBUG_WEBSOCKETS("\n"); +#ifdef WS_DEBUG + WS_PRINTLN(); +#endif } clientDisconnect(client, 1000); } @@ -439,41 +524,45 @@ String WebSockets::base64_encode(uint8_t * data, size_t length) { * @param n size_t byte count * @return true if ok */ -bool WebSockets::readWait(WSclient_t * client, uint8_t *out, size_t n) { +bool WebSockets::readWait(WSclient_t & client, uint8_t *out, size_t n) { unsigned long t = millis(); size_t len; while(n > 0) { - if(!client->tcp) { - DEBUG_WEBSOCKETS("[readWait] tcp is null!\n"); + if(!client.tcp) { +#ifdef WS_DEBUG + WS_PRINTLN("[readWait] tcp is null!"); +#endif return false; } - if(!client->tcp->connected()) { - DEBUG_WEBSOCKETS("[readWait] not connected!\n"); + if(!client.tcp.connected()) { +#ifdef WS_DEBUG + WS_PRINTLN("[readWait] not connected!"); +#endif return false; } if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) { - DEBUG_WEBSOCKETS("[readWait] receive TIMEOUT!\n"); +#ifdef WS_DEBUG + WS_PRINTLN("[readWait] receive TIMEOUT!"); +#endif return false; } - if(!client->tcp->available()) { + if(!client.tcp.available()) { #ifdef ESP8266 delay(0); #endif continue; } - len = client->tcp->read((uint8_t*) out, n); + len = client.tcp.read((uint8_t*) out, n); if(len) { t = millis(); out += len; n -= len; - //DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n); } else { - //DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n); } #ifdef ESP8266 delay(0); diff --git a/src/WebSockets.h b/src/WebSockets.h index ffccf80..c250621 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -27,13 +27,26 @@ #include -//#define DEBUG_WEBSOCKETS(...) Serial1.printf( __VA_ARGS__ ) - -#ifndef DEBUG_WEBSOCKETS -#define DEBUG_WEBSOCKETS(...) +//#define DEBUG_WEBSOCKETS + +// those macro have been added to save program space +//#define WS_DEBUG //unmute this to display debug print from websockets.h and cpp +//#define WS_CLIENT_DEBUG //unmute this to display debug print from websocketsClient.h and cpp +//#define WS_SERVER_DEBUG //unmute this to display debug print from websocketsServer + +#ifdef DEBUG_WEBSOCKETS +#define WS_PRINT(x) Serial.print(x); +#define WS_PRINTLN(x) Serial.println(x); +#else +#define WS_PRINT(x) +#define WS_PRINTLN(x) #define NODEBUG_WEBSOCKETS #endif + + //Unmute to select Ethernet2 sheild library +//#define W5500_H //remove with ethernet library 2.0 + #ifdef ESP8266 #define WEBSOCKETS_MAX_DATA_SIZE (15*1024) #define WEBSOCKETS_USE_BIG_MEM @@ -45,15 +58,22 @@ #define WEBSOCKETS_TCP_TIMEOUT (1500) #define NETWORK_ESP8266 (1) -#define NETWORK_W5100 (2) +//#define NETWORK_W5100 (2) //replace with ethernet library 2.0 +#define NETWORK_W5X00 (2) #define NETWORK_ENC28J60 (3) +//#define NETWORK_W5500 (4) //replace with ethernet library 2.0 + // select Network type based #ifdef ESP8266 #define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 +/*#elif defined W5500_H +#define WEBSOCKETS_NETWORK_TYPE NETWORK_W5500 #else -#define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 +#define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100*/ +#else +#define WEBSOCKETS_NETWORK_TYPE NETWORK_W5X00 //replace with ethernet library 2.0 #endif @@ -67,10 +87,10 @@ #define WEBSOCKETS_NETWORK_CLASS WiFiClient #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_W5100) - -#include -#include +//#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_W5100) //replace with ethernet library 2.0 +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_W5X00) +#include +#include #define WEBSOCKETS_NETWORK_CLASS EthernetClient #define WEBSOCKETS_NETWORK_SERVER_CLASS EthernetServer @@ -80,10 +100,28 @@ #define WEBSOCKETS_NETWORK_CLASS UIPClient #define WEBSOCKETS_NETWORK_SERVER_CLASS UIPServer +/* +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_W5500) //remove with ethernet library 2.0 +#include +#include +#define WEBSOCKETS_NETWORK_CLASS EthernetClient +#define WEBSOCKETS_NETWORK_SERVER_CLASS EthernetServer +*/ + #else -#error "no network type selected!" +//#error "no network type selected!" #endif +/* +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_W5500) //replace with ethernet library 2.0 + #define WEBSOCKETS_SERVER_CLIENT_MAX (8) +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_W5100) + #define WEBSOCKETS_SERVER_CLIENT_MAX (4)*/ +#ifdef MAX_SOCK_NUM + #define WEBSOCKETS_SERVER_CLIENT_MAX (MAX_SOCK_NUM) +#else + #define WEBSOCKETS_SERVER_CLIENT_MAX (5) +#endif typedef enum { WSC_NOT_CONNECTED, @@ -110,12 +148,30 @@ typedef enum { ///< %xB-F are reserved for further control frames } WSopcode_t; -typedef struct { +struct WSclient_t { + WSclient_t() : + num(-1), + status(WSC_NOT_CONNECTED), + tcp(NULL), + cUrl(""), + cCode(0), + cKey(""), + cProtocol(""), + cVersion(0), + cIsUpgrade(false), + cIsWebsocket(false) + { + tcp = WEBSOCKETS_NETWORK_CLASS(); +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + client.isSSL = false; + client.ssl = NULL; +#endif + }; uint8_t num; ///< connection number WSclientsStatus_t status; - WEBSOCKETS_NETWORK_CLASS * tcp; + WEBSOCKETS_NETWORK_CLASS tcp; #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) bool isSSL; ///< run in ssl mode @@ -133,23 +189,23 @@ typedef struct { String cProtocol; ///< client Sec-WebSocket-Protocol String cExtensions; ///< client Sec-WebSocket-Extensions uint16_t cVersion; ///< client Sec-WebSocket-Version + bool operator==(const WSclient_t ws) { return num < WEBSOCKETS_SERVER_CLIENT_MAX && tcp == ws.tcp;}; -} WSclient_t; +}; class WebSockets { protected: - virtual void clientDisconnect(WSclient_t * client); - virtual bool clientIsConnected(WSclient_t * client); - - virtual void messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length); + virtual void clientDisconnect(WSclient_t & client); + virtual bool clientIsConnected(WSclient_t & client); - void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0); - void sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool mask = false, bool fin = true, bool headerToPayload = false); + virtual void messageReceived(WSclient_t & client, WSopcode_t opcode, uint8_t * payload, size_t length); + void clientDisconnect(WSclient_t & client, uint16_t code, char * reason = NULL, size_t reasonLen = 0); + void sendFrame(WSclient_t & client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool mask = false, bool fin = true, bool headerToPayload = false); - void handleWebsocket(WSclient_t * client); + void handleWebsocket(WSclient_t & client); - bool readWait(WSclient_t * client, uint8_t *out, size_t n); + bool readWait(WSclient_t & client, uint8_t *out, size_t n); String acceptKey(String clientKey); String base64_encode(uint8_t * data, size_t length); diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index d398aad..c29f3f4 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -43,23 +43,6 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url) #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) _fingerprint = ""; #endif - - _client.num = 0; - _client.status = WSC_NOT_CONNECTED; - _client.tcp = NULL; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - _client.isSSL = false; - _client.ssl = NULL; -#endif - _client.cUrl = url; - _client.cCode = 0; - _client.cIsUpgrade = false; - _client.cIsWebsocket = true; - _client.cKey = ""; - _client.cAccept = ""; - _client.cProtocol = ""; - _client.cExtensions = ""; - _client.cVersion = 0; #ifdef ESP8266 randomSeed(RANDOM_REG32); @@ -89,49 +72,46 @@ void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String f * called in arduino loop */ void WebSocketsClient::loop(void) { - if(!clientIsConnected(&_client)) { + if(!clientIsConnected(_client)) { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) if(_client.isSSL) { - DEBUG_WEBSOCKETS("[WS-Client] connect wss...\n"); +#ifdef WS_CLIENT_DEBUG + WS_PRINTLN("[WS-Client] connect wss..."); +#endif if(_client.ssl) { delete _client.ssl; _client.ssl = NULL; - _client.tcp = NULL; } _client.ssl = new WiFiClientSecure(); - _client.tcp = _client.ssl; } else { - DEBUG_WEBSOCKETS("[WS-Client] connect ws...\n"); - if(_client.tcp) { - delete _client.tcp; - _client.tcp = NULL; - } - _client.tcp = new WiFiClient(); - } -#else - _client.tcp = new WEBSOCKETS_NETWORK_CLASS(); +#ifdef WS_CLIENT_DEBUG + WS_PRINTLN("[WS-Client] connect ws..."); #endif - - if(!_client.tcp) { - DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); - return; } +#endif - if(_client.tcp->connect(_host.c_str(), _port)) { - DEBUG_WEBSOCKETS("[WS-Client] connected to %s:%u.\n", _host.c_str(), _port); - + if(_client.tcp.connect(_host.c_str(), _port)) { +#ifdef WS_CLIENT_DEBUG + WS_PRINT("[WS-Client] connected to "); + WS_PRINT(_host.c_str()); + WS_PRINT(":"); + WS_PRINT(_port); + WS_PRINTLN("."); +#endif _client.status = WSC_HEADER; // set Timeout for readBytesUntil and readStringUntil - _client.tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); + _client.tcp.setTimeout(WEBSOCKETS_TCP_TIMEOUT); #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - _client.tcp->setNoDelay(true); + _client.tcp.setNoDelay(true); if(_client.isSSL && _fingerprint.length()) { if(!_client.ssl->verify(_fingerprint.c_str(), _host.c_str())) { - DEBUG_WEBSOCKETS("[WS-Client] certificate mismatch\n"); +#ifdef WS_CLIENT_DEBUG + WS_PRINTLN("[WS-Client] creating Network class failed!"); +#endif WebSockets::clientDisconnect(&_client, 1000); return; } @@ -139,10 +119,16 @@ void WebSocketsClient::loop(void) { #endif // send Header to Server - sendHeader(&_client); + sendHeader(_client); } else { - DEBUG_WEBSOCKETS("[WS-Client] connection to %s:%u Faild\n", _host.c_str(), _port); +#ifdef WS_CLIENT_DEBUG + WS_PRINT("[WS-Client] connection to "); + WS_PRINT(_host.c_str()); + WS_PRINT(":"); + WS_PRINT(_port); + WS_PRINTLN(" Faild"); +#endif delay(10); //some litle delay to not flood the server } } else { @@ -169,8 +155,8 @@ void WebSocketsClient::sendTXT(uint8_t * payload, size_t length, bool headerToPa if(length == 0) { length = strlen((const char *) payload); } - if(clientIsConnected(&_client)) { - sendFrame(&_client, WSop_text, payload, length, true, true, headerToPayload); + if(clientIsConnected(_client)) { + sendFrame(_client, WSop_text, payload, length, true, true, headerToPayload); } } @@ -198,8 +184,8 @@ void WebSocketsClient::sendTXT(String payload) { * @param headerToPayload bool (see sendFrame for more details) */ void WebSocketsClient::sendBIN(uint8_t * payload, size_t length, bool headerToPayload) { - if(clientIsConnected(&_client)) { - sendFrame(&_client, WSop_binary, payload, length, true, true, headerToPayload); + if(clientIsConnected(_client)) { + sendFrame(_client, WSop_binary, payload, length, true, true, headerToPayload); } } @@ -212,8 +198,8 @@ void WebSocketsClient::sendBIN(const uint8_t * payload, size_t length) { * @param num uint8_t client id */ void WebSocketsClient::disconnect(void) { - if(clientIsConnected(&_client)) { - WebSockets::clientDisconnect(&_client, 1000); + if(clientIsConnected(_client)) { + WebSockets::clientDisconnect(_client, 1000); } } @@ -228,7 +214,7 @@ void WebSocketsClient::disconnect(void) { * @param payload uint8_t * * @param lenght size_t */ -void WebSocketsClient::messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t lenght) { +void WebSocketsClient::messageReceived(WSclient_t & client, WSopcode_t opcode, uint8_t * payload, size_t length) { WStype_t type = WStype_ERROR; switch(opcode) { @@ -239,52 +225,35 @@ void WebSocketsClient::messageRecived(WSclient_t * client, WSopcode_t opcode, ui type = WStype_BIN; break; } - - runCbEvent(type, payload, lenght); - + runCbEvent(type, payload, length); } /** * Disconnect an client * @param client WSclient_t * ptr to the client struct */ -void WebSocketsClient::clientDisconnect(WSclient_t * client) { - +void WebSocketsClient::clientDisconnect(WSclient_t & client) { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - if(client->isSSL && client->ssl) { - if(client->ssl->connected()) { - client->ssl->flush(); - client->ssl->stop(); + if(client.isSSL && client->ssl) { + if(client.ssl->connected()) { + client.ssl->flush(); + client.ssl->stop(); } - delete client->ssl; - client->ssl = NULL; - client->tcp = NULL; + delete client.ssl; } #endif - - if(client->tcp) { - if(client->tcp->connected()) { - client->tcp->flush(); - client->tcp->stop(); + if(client.tcp) { + if(client.tcp.connected()) { + client.tcp.flush(); + client.tcp.stop(); } - delete client->tcp; - client->tcp = NULL; } - client->cCode = 0; - client->cKey = ""; - client->cAccept = ""; - client->cProtocol = ""; - client->cVersion = 0; - client->cIsUpgrade = false; - client->cIsWebsocket = false; - - client->status = WSC_NOT_CONNECTED; - - DEBUG_WEBSOCKETS("[WS-Client] client disconnected.\n"); - + client = WSclient_t(); //reset client to 0 +#ifdef WS_CLIENT_DEBUG + WS_PRINTLN("[WS-Client] client disconnected."); +#endif runCbEvent(WStype_DISCONNECTED, NULL, 0); - } /** @@ -292,30 +261,28 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { * @param client WSclient_t * ptr to the client struct * @return true = conneted */ -bool WebSocketsClient::clientIsConnected(WSclient_t * client) { - - if(!client->tcp) { +bool WebSocketsClient::clientIsConnected(WSclient_t & client) { + if(!client.tcp) { return false; } - - if(client->tcp->connected()) { - if(client->status != WSC_NOT_CONNECTED) { + if(client.tcp.connected()) { + if(client.status != WSC_NOT_CONNECTED) { return true; } } else { // client lost - if(client->status != WSC_NOT_CONNECTED) { - DEBUG_WEBSOCKETS("[WS-Client] connection lost.\n"); + if(client.status != WSC_NOT_CONNECTED) { +#ifdef WS_CLIENT_DEBUG + WS_PRINTLN("[WS-Client] connection lost."); +#endif // do cleanup clientDisconnect(client); } } - - if(client->tcp) { + if(client.tcp) { // do cleanup clientDisconnect(client); } - return false; } @@ -323,17 +290,23 @@ bool WebSocketsClient::clientIsConnected(WSclient_t * client) { * Handel incomming data from Client */ void WebSocketsClient::handleClientData(void) { - int len = _client.tcp->available(); +#ifdef WS_CLIENT_DEBUG + WS_PRINTLN("handle client data"); +#endif + int len = _client.tcp.available(); if(len > 0) { switch(_client.status) { case WSC_HEADER: - handleHeader(&_client); + handleHeader(_client); + WS_PRINTLN("data:handleHeader"); break; case WSC_CONNECTED: - WebSockets::handleWebsocket(&_client); + WebSockets::handleWebsocket(_client); + WS_PRINTLN("data: handle WS"); break; default: - WebSockets::clientDisconnect(&_client, 1002); + WebSockets::clientDisconnect(_client, 1002); + WS_PRINTLN("data: disc"); break; } } @@ -346,104 +319,119 @@ void WebSocketsClient::handleClientData(void) { * send the WebSocket header to Server * @param client WSclient_t * ptr to the client struct */ -void WebSocketsClient::sendHeader(WSclient_t * client) { - - DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header...\n"); - +void WebSocketsClient::sendHeader(WSclient_t & client) { +#ifdef WS_CLIENT_DEBUG + WS_PRINTLN("[WS-Client][sendHeader] sending header..."); +#endif uint8_t randomKey[16] = { 0 }; for(uint8_t i = 0; i < sizeof(randomKey); i++) { randomKey[i] = random(0xFF); } - client->cKey = base64_encode(&randomKey[0], 16); + client.cKey = base64_encode(&randomKey[0], 16); #ifndef NODEBUG_WEBSOCKETS unsigned long start = micros(); #endif - String handshake = "GET " + client->cUrl + " HTTP/1.1\r\n" + String handshake = "GET " + client.cUrl + " HTTP/1.1\r\n" "Host: " + _host + "\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" "User-Agent: arduino-WebSocket-Client\r\n" "Sec-WebSocket-Version: 13\r\n" "Sec-WebSocket-Protocol: arduino\r\n" - "Sec-WebSocket-Key: " + client->cKey + "\r\n"; + "Sec-WebSocket-Key: " + client.cKey + "\r\n"; - if(client->cExtensions.length() > 0) { - handshake += "Sec-WebSocket-Extensions: " + client->cExtensions + "\r\n"; + if(client.cExtensions.length() > 0) { + handshake += "Sec-WebSocket-Extensions: " + client.cExtensions + "\r\n"; } handshake += "\r\n"; - client->tcp->write(handshake.c_str(), handshake.length()); - - DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header... Done (%uus).\n", (micros() - start)); - + client.tcp.write(handshake.c_str(), handshake.length()); +#ifdef WS_CLIENT_DEBUG + WS_PRINT("[WS-Client][sendHeader] sending header... Done ("); + WS_PRINT((micros() - start)); + WS_PRINTLN("us)."); +#endif } /** * handle the WebSocket header reading * @param client WSclient_t * ptr to the client struct */ -void WebSocketsClient::handleHeader(WSclient_t * client) { - - String headerLine = client->tcp->readStringUntil('\n'); +void WebSocketsClient::handleHeader(WSclient_t & client) { + String headerLine = client.tcp.readStringUntil('\n'); headerLine.trim(); // remove \r if(headerLine.length() > 0) { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine.c_str()); - +#ifdef WS_CLIENT_DEBUG + WS_PRINT("[WS-Client][handleHeader] RX: "); + WS_PRINTLN(headerLine.c_str()); +#endif if(headerLine.startsWith("HTTP/1.")) { // "HTTP/1.1 101 Switching Protocols" - client->cCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt(); + client.cCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt(); } else if(headerLine.indexOf(':')) { String headerName = headerLine.substring(0, headerLine.indexOf(':')); String headerValue = headerLine.substring(headerLine.indexOf(':') + 2); if(headerName.equalsIgnoreCase("Connection")) { if(headerValue.indexOf("Upgrade") >= 0) { - client->cIsUpgrade = true; + client.cIsUpgrade = true; } } else if(headerName.equalsIgnoreCase("Upgrade")) { if(headerValue.equalsIgnoreCase("websocket")) { - client->cIsWebsocket = true; + client.cIsWebsocket = true; } } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Accept")) { - client->cAccept = headerValue; - client->cAccept.trim(); // see rfc6455 + client.cAccept = headerValue; + client.cAccept.trim(); // see rfc6455 } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Protocol")) { - client->cProtocol = headerValue; + client.cProtocol = headerValue; } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Extensions")) { - client->cExtensions = headerValue; + client.cExtensions = headerValue; } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Version")) { - client->cVersion = headerValue.toInt(); + client.cVersion = headerValue.toInt(); } } else { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine.c_str()); +#ifdef WS_CLIENT_DEBUG + WS_PRINT("[WS-Client][handleHeader] Header error ("); + WS_PRINT(headerLine.c_str()); + WS_PRINTLN(")"); +#endif } } else { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header read fin.\n"); - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Client settings:\n"); - - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cURL: %s\n", client->cUrl.c_str()); - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cKey: %s\n", client->cKey.c_str()); - - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Server header:\n"); - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cCode: %d\n", client->cCode); - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cIsUpgrade: %d\n", client->cIsUpgrade); - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cIsWebsocket: %d\n", client->cIsWebsocket); - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cAccept: %s\n", client->cAccept.c_str()); - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cProtocol: %s\n", client->cProtocol.c_str()); - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cExtensions: %s\n", client->cExtensions.c_str()); - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cVersion: %d\n", client->cVersion); - - bool ok = (client->cIsUpgrade && client->cIsWebsocket); +#ifdef WS_CLIENT_DEBUG + WS_PRINTLN("[WS-Client][handleHeader] Header read fin."); + WS_PRINTLN("[WS-Client][handleHeader] Client settings:"); + WS_PRINT("[WS-Client][handleHeader] - cURL: "); + WS_PRINTLN(client.cUrl.c_str()); + WS_PRINTLN("[WS-Client][handleHeader] - cKey: "); + WS_PRINTLN(client.cKey.c_str()); + WS_PRINTLN("[WS-Client][handleHeader] Server header:"); + WS_PRINT("[WS-Client][handleHeader] - cCode: "); + WS_PRINTLN(client.cCode); + WS_PRINT("[WS-Client][handleHeader] - cIsUpgrade: "); + WS_PRINTLN(client.cIsUpgrade); + WS_PRINT("[WS-Client][handleHeader] - cIsWebsocket: "); + WS_PRINTLN(client.cIsWebsocket); + WS_PRINT("[WS-Client][handleHeader] - cAccept: "); + WS_PRINTLN(client.cAccept.c_str()); + WS_PRINT("[WS-Client][handleHeader] - cProtocol: "); + WS_PRINTLN(client.cProtocol.c_str()); + WS_PRINT("[WS-Client][handleHeader] - cExtensions: "); + WS_PRINTLN(client.cExtensions.c_str()); + WS_PRINT("[WS-Client][handleHeader] - cVersion: "); + WS_PRINTLN(client.cVersion); +#endif + bool ok = (client.cIsUpgrade && client.cIsWebsocket); if(ok) { - switch(client->cCode) { + switch(client.cCode) { case 101: ///< Switching Protocols break; @@ -451,38 +439,45 @@ void WebSocketsClient::handleHeader(WSclient_t * client) { // todo handle login default: ///< Server dont unterstand requrst ok = false; - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] serverCode is not 101 (%d)\n", client->cCode); +#ifdef WS_CLIENT_DEBUG + WS_PRINT("[WS-Client][handleHeader] serverCode is not 101 ("); + WS_PRINT(client.cCode); + WS_PRINTLN(")"); +#endif clientDisconnect(client); break; } } if(ok) { - if(client->cAccept.length() == 0) { + if(client.cAccept.length() == 0) { ok = false; } else { // generate Sec-WebSocket-Accept key for check - String sKey = acceptKey(client->cKey); - if(sKey != client->cAccept) { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Sec-WebSocket-Accept is wrong\n"); + String sKey = acceptKey(client.cKey); + if(sKey != client.cAccept) { +#ifdef WS_CLIENT_DEBUG + WS_PRINTLN("[WS-Client][handleHeader] Sec-WebSocket-Accept is wrong"); +#endif ok = false; } } } if(ok) { +#ifdef WS_CLIENT_DEBUG + WS_PRINTLN("[WS-Client][handleHeader] Websocket connection init done."); +#endif + client.status = WSC_CONNECTED; - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Websocket connection init done.\n"); - - client->status = WSC_CONNECTED; - - runCbEvent(WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length()); + runCbEvent(WStype_CONNECTED, (uint8_t *) client.cUrl.c_str(), client.cUrl.length()); } else { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n"); - client->tcp->write("This is a webSocket client!"); +#ifdef WS_CLIENT_DEBUG + WS_PRINTLN("[WS-Client][handleHeader] no Websocket connection close."); +#endif + client.tcp.write("This is a webSocket client!"); clientDisconnect(client); } } } - diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 6a2c60e..12e239b 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -70,16 +70,16 @@ class WebSocketsClient: private WebSockets { WebSocketClientEvent _cbEvent; - void messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length); + void messageReceived(WSclient_t & client, WSopcode_t opcode, uint8_t * payload, size_t length); - void clientDisconnect(WSclient_t * client); - bool clientIsConnected(WSclient_t * client); + void clientDisconnect(WSclient_t & client); + bool clientIsConnected(WSclient_t & client); void handleNewClients(void); void handleClientData(void); - void sendHeader(WSclient_t * client); - void handleHeader(WSclient_t * client); + void sendHeader(WSclient_t & client); + void handleHeader(WSclient_t & client); /** * called for sending a Event to the app diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 5ec4eca..5d02257 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -25,18 +25,14 @@ #include "WebSockets.h" #include "WebSocketsServer.h" -WebSocketsServer::WebSocketsServer(uint16_t port) { - _port = port; - _server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port); - - _cbEvent = NULL; - +WebSocketsServer::WebSocketsServer(uint16_t port) : + _port(port), _server(new WEBSOCKETS_NETWORK_SERVER_CLASS(port)), _cbEvent(NULL) +{ } WebSocketsServer::~WebSocketsServer() { // disconnect all clients disconnect(); - // TODO how to close server? } @@ -44,27 +40,6 @@ WebSocketsServer::~WebSocketsServer() { * calles to init the Websockets server */ void WebSocketsServer::begin(void) { - WSclient_t * client; - - // init client storage - for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { - client = &_clients[i]; - - client->num = i; - client->status = WSC_NOT_CONNECTED; - client->tcp = NULL; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - client->isSSL = false; - client->ssl = NULL; -#endif - client->cUrl = ""; - client->cCode = 0; - client->cKey = ""; - client->cProtocol = ""; - client->cVersion = 0; - client->cIsUpgrade = false; - client->cIsWebsocket = false; - } #ifdef ESP8266 randomSeed(RANDOM_REG32); @@ -74,16 +49,51 @@ void WebSocketsServer::begin(void) { #endif _server->begin(); +#ifdef WS_SERVER_DEBUG + WS_PRINTLN("[WS-Server] Server Started."); +#endif - DEBUG_WEBSOCKETS("[WS-Server] Server Started.\n"); } /** * called in arduino loop */ void WebSocketsServer::loop(void) { - handleNewClients(); - handleClientData(); + //check if client, if it is a new client + WSclient_t wsClient; + wsClient.tcp = _server->available(); + + //monitor for lost connect to clear socket + if ( timeOutCounter > timeoutClient ) { + for (uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { + clientIsConnected(_clients[i]); + } + timeOutCounter = 0; + } + timeOutCounter++; + + if (wsClient.tcp) { + for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { + if( _clients[i] == wsClient ) {//not a new client, handle data + handleClientData(_clients[i]); + return; + } + } + //if you got to that point, it is a new client + for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { + if (_clients[i].num >= WEBSOCKETS_SERVER_CLIENT_MAX) { //if emty slot, assing new client then handle it. + wsClient.num = i; + _clients[i] = wsClient; + handleNewClients(_clients[i]); + return; + } + + } + wsClient.tcp.stop(); //close connection is no free spot +#ifdef WS_SERVER_DEBUG + WS_PRINTLN("[WS-Server] No free socket, connection close"); +#endif + } } /** @@ -108,7 +118,7 @@ void WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bo if(length == 0) { length = strlen((const char *) payload); } - WSclient_t * client = &_clients[num]; + WSclient_t & client = _clients[num]; if(clientIsConnected(client)) { sendFrame(client, WSop_text, payload, length, false, true, headerToPayload); } @@ -137,13 +147,12 @@ void WebSocketsServer::sendTXT(uint8_t num, String payload) { * @param headerToPayload bool (see sendFrame for more details) */ void WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool headerToPayload) { - WSclient_t * client; if(length == 0) { length = strlen((const char *) payload); } for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { - client = &_clients[i]; + WSclient_t & client = _clients[i]; if(clientIsConnected(client)) { sendFrame(client, WSop_text, payload, length, false, true, headerToPayload); } @@ -180,7 +189,7 @@ void WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length, bo if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) { return; } - WSclient_t * client = &_clients[num]; + WSclient_t & client = _clients[num]; if(clientIsConnected(client)) { sendFrame(client, WSop_binary, payload, length, false, true, headerToPayload); } @@ -197,9 +206,8 @@ void WebSocketsServer::sendBIN(uint8_t num, const uint8_t * payload, size_t leng * @param headerToPayload bool (see sendFrame for more details) */ void WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload) { - WSclient_t * client; for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { - client = &_clients[i]; + WSclient_t & client = _clients[i]; if(clientIsConnected(client)) { sendFrame(client, WSop_binary, payload, length, false, true, headerToPayload); } @@ -217,9 +225,8 @@ void WebSocketsServer::broadcastBIN(const uint8_t * payload, size_t length) { * disconnect all clients */ void WebSocketsServer::disconnect(void) { - WSclient_t * client; for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { - client = &_clients[i]; + WSclient_t & client = _clients[i]; if(clientIsConnected(client)) { WebSockets::clientDisconnect(client, 1000); } @@ -234,13 +241,12 @@ void WebSocketsServer::disconnect(uint8_t num) { if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) { return; } - WSclient_t * client = &_clients[num]; + WSclient_t & client = _clients[num]; if(clientIsConnected(client)) { WebSockets::clientDisconnect(client, 1000); } } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) /** * get an IP for a client * @param num uint8_t client id @@ -248,15 +254,13 @@ void WebSocketsServer::disconnect(uint8_t num) { */ IPAddress WebSocketsServer::remoteIP(uint8_t num) { if(num < WEBSOCKETS_SERVER_CLIENT_MAX) { - WSclient_t * client = &_clients[num]; + WSclient_t & client = _clients[num]; if(clientIsConnected(client)) { - return client->tcp->remoteIP(); + return client.tcp.remoteIP(); } } - return IPAddress(); } -#endif //################################################################################# //################################################################################# @@ -269,7 +273,8 @@ IPAddress WebSocketsServer::remoteIP(uint8_t num) { * @param payload uint8_t * * @param lenght size_t */ -void WebSocketsServer::messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t lenght) { + +void WebSocketsServer::messageReceived(WSclient_t & client, WSopcode_t opcode, uint8_t * payload, size_t lenght) { WStype_t type = WStype_ERROR; switch(opcode) { @@ -281,51 +286,40 @@ void WebSocketsServer::messageRecived(WSclient_t * client, WSopcode_t opcode, ui break; } - runCbEvent(client->num, type, payload, lenght); - + runCbEvent(client.num, type, payload, lenght); } - /** * Disconnect an client * @param client WSclient_t * ptr to the client struct */ -void WebSocketsServer::clientDisconnect(WSclient_t * client) { - +void WebSocketsServer::clientDisconnect(WSclient_t & client) { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - if(client->isSSL && client->ssl) { - if(client->ssl->connected()) { - client->ssl->flush(); - client->ssl->stop(); + if(client.isSSL && client.ssl) { + if(client.ssl->connected()) { + client.ssl->flush(); + client.ssl->stop(); } delete client->ssl; - client->ssl = NULL; - client->tcp = NULL; + client.ssl = NULL; } #endif - if(client->tcp) { - if(client->tcp->connected()) { - client->tcp->flush(); - client->tcp->stop(); + if(client.tcp) { + if(client.tcp.connected()) { + client.tcp.flush(); + client.tcp.stop(); } - delete client->tcp; - client->tcp = NULL; } - client->cUrl = ""; - client->cKey = ""; - client->cProtocol = ""; - client->cVersion = 0; - client->cIsUpgrade = false; - client->cIsWebsocket = false; - - client->status = WSC_NOT_CONNECTED; - - DEBUG_WEBSOCKETS("[WS-Server][%d] client disconnected.\n", client->num); - - runCbEvent(client->num, WStype_DISCONNECTED, NULL, 0); +#ifdef WS_SERVER_DEBUG + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINTLN("] client disconnected."); +#endif + runCbEvent(client.num, WStype_DISCONNECTED, NULL, 0); + client = WSclient_t(); //reset client to 0 } /** @@ -333,26 +327,32 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { * @param client WSclient_t * ptr to the client struct * @return true = conneted */ -bool WebSocketsServer::clientIsConnected(WSclient_t * client) { - if(!client->tcp) { +bool WebSocketsServer::clientIsConnected(WSclient_t & client) { + if (client.num >= WEBSOCKETS_SERVER_CLIENT_MAX) return false; + if (!client.tcp) { + clientDisconnect(client); return false; } - if(client->tcp->connected()) { - if(client->status != WSC_NOT_CONNECTED) { + if(client.tcp.connected()) { + if(client.status != WSC_NOT_CONNECTED) { return true; } } else { // client lost - if(client->status != WSC_NOT_CONNECTED) { - DEBUG_WEBSOCKETS("[WS-Server][%d] client connection lost.\n", client->num); + if(client.status != WSC_NOT_CONNECTED) { +#ifdef WS_SERVER_DEBUG + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINTLN("] client connection lost."); +#endif // do cleanup clientDisconnect(client); } } - if(client->tcp) { + if(client.tcp) { // do cleanup clientDisconnect(client); } @@ -363,80 +363,67 @@ bool WebSocketsServer::clientIsConnected(WSclient_t * client) { /** * Handle incomming Connection Request */ -void WebSocketsServer::handleNewClients(void) { - WSclient_t * client; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + +void WebSocketsServer::handleNewClients(WSclient_t & client) { + bool ok = false; + client.status = WSC_HEADER; +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) //not shure for ESP8266 while(_server->hasClient()) { +#endif + if(!clientIsConnected(client)) { +#ifdef WS_SERVER_DEBUG + WS_PRINTLN("fail to make new connection"); #endif - bool ok = false; - // search free list entry for client - for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { - client = &_clients[i]; + return; + } - // state is not connected or tcp connection is lost - if(!clientIsConnected(client)) { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - // store new connection - client->tcp = new WEBSOCKETS_NETWORK_CLASS(_server->available()); -#else - client->tcp = new WEBSOCKETS_NETWORK_CLASS(_server->available()); + client.isSSL = false; + client.tcp.setNoDelay(true); #endif - if(!client->tcp) { - DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); - return; - } + // set Timeout for readBytesUntil and readStringUntil + client.tcp.setTimeout(WEBSOCKETS_TCP_TIMEOUT); #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - client->isSSL = false; - client->tcp->setNoDelay(true); + IPAddress ip = client.tcp.remoteIP(); +#ifdef WS_SERVER_DEBUG + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINT("] new client from "); + WS_PRINT(ip[0]); + WS_PRINT("."); + WS_PRINT(ip[1]); + WS_PRINT("."); + WS_PRINT(ip[2]); + WS_PRINT("."); + WS_PRINTLN(ip[3]); #endif - // set Timeout for readBytesUntil and readStringUntil - client->tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); - client->status = WSC_HEADER; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - IPAddress ip = client->tcp->remoteIP(); - DEBUG_WEBSOCKETS("[WS-Server][%d] new client from %d.%d.%d.%d\n", client->num, ip[0], ip[1], ip[2], ip[3]); #else - DEBUG_WEBSOCKETS("[WS-Server][%d] new client\n", client->num); +#ifdef WS_SERVER_DEBUG + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINTLN("] new client"); #endif - ok = true; - break; - } - } - - if(!ok) { - // no free space to handle client - WEBSOCKETS_NETWORK_CLASS tcpClient = _server->available(); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - IPAddress ip = client->tcp->remoteIP(); - DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); -#else - DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n"); #endif - tcpClient.stop(); - } + + ok = true; #ifdef ESP8266 delay(0); #endif #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - } + #endif + } -/** - * Handel incomming data from Client - */ -void WebSocketsServer::handleClientData(void) { - WSclient_t * client; - for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { - client = &_clients[i]; +void WebSocketsServer::handleClientData(WSclient_t & client) { if(clientIsConnected(client)) { - int len = client->tcp->available(); + int len = client.tcp.available(); if(len > 0) { - switch(client->status) { + switch(client.status) { case WSC_HEADER: handleHeader(client); break; @@ -452,114 +439,146 @@ void WebSocketsServer::handleClientData(void) { #ifdef ESP8266 delay(0); #endif - } } /** * handle the WebSocket header reading * @param client WSclient_t * ptr to the client struct */ -void WebSocketsServer::handleHeader(WSclient_t * client) { +void WebSocketsServer::handleHeader(WSclient_t & client) { - String headerLine = client->tcp->readStringUntil('\n'); + String headerLine = client.tcp.readStringUntil('\n'); headerLine.trim(); // remove \r if(headerLine.length() > 0) { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine.c_str()); - +#ifdef WS_SERVER_DEBUG + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINT("][handleHeader] RX: "); + WS_PRINTLN(headerLine.c_str()); +#endif // websocket request starts allways with GET see rfc6455 if(headerLine.startsWith("GET ")) { // cut URL out - client->cUrl = headerLine.substring(4, headerLine.indexOf(' ', 4)); + client.cUrl = headerLine.substring(4, headerLine.indexOf(' ', 4)); } else if(headerLine.indexOf(':')) { String headerName = headerLine.substring(0, headerLine.indexOf(':')); String headerValue = headerLine.substring(headerLine.indexOf(':') + 2); if(headerName.equalsIgnoreCase("Connection")) { if(headerValue.indexOf("Upgrade") >= 0) { - client->cIsUpgrade = true; + client.cIsUpgrade = true; } } else if(headerName.equalsIgnoreCase("Upgrade")) { if(headerValue.equalsIgnoreCase("websocket")) { - client->cIsWebsocket = true; + client.cIsWebsocket = true; } } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Version")) { - client->cVersion = headerValue.toInt(); + client.cVersion = headerValue.toInt(); } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Key")) { - client->cKey = headerValue; - client->cKey.trim(); // see rfc6455 + client.cKey = headerValue; + client.cKey.trim(); // see rfc6455 } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Protocol")) { - client->cProtocol = headerValue; + client.cProtocol = headerValue; } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Extensions")) { - client->cExtensions = headerValue; + client.cExtensions = headerValue; } } else { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine.c_str()); +#ifdef WS_SERVER_DEBUG + WS_PRINT("[WS-Client][handleHeader] Header error ("); + WS_PRINT(headerLine.c_str()); + WS_PRINTLN(")"); +#endif } } else { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Header read fin.\n", client->num); - - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cURL: %s\n", client->num, client->cUrl.c_str()); - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cIsUpgrade: %d\n", client->num, client->cIsUpgrade); - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cIsWebsocket: %d\n", client->num, client->cIsWebsocket); - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cKey: %s\n", client->num, client->cKey.c_str()); - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cProtocol: %s\n", client->num, client->cProtocol.c_str()); - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cExtensions: %s\n", client->num, client->cExtensions.c_str()); - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cVersion: %d\n", client->num, client->cVersion); - - bool ok = (client->cIsUpgrade && client->cIsWebsocket); +#ifdef WS_SERVER_DEBUG + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINTLN("][handleHeader] Header read fin."); + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINT("][handleHeader] - cURL: "); + WS_PRINTLN(client.cUrl.c_str()); + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINT("][handleHeader] - cIsUpgrade: "); + WS_PRINTLN(client.cIsUpgrade); + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINT("][handleHeader] - cIsWebsocket: "); + WS_PRINTLN(client.cIsWebsocket); + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINT("][handleHeader] - cKey: "); + WS_PRINTLN(client.cKey.c_str()); + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINT("][handleHeader] - cProtocol: "); + WS_PRINTLN(client.cProtocol.c_str()); + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINT("][handleHeader] - cExtensions: "); + WS_PRINTLN(client.cExtensions.c_str()); + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINT("][handleHeader] - cVersion: "); + WS_PRINTLN(client.cVersion); +#endif + bool ok = (client.cIsUpgrade && client.cIsWebsocket); if(ok) { - if(client->cUrl.length() == 0) { + if(client.cUrl.length() == 0) { ok = false; } - if(client->cKey.length() == 0) { + if(client.cKey.length() == 0) { ok = false; } - if(client->cVersion != 13) { + if(client.cVersion != 13) { ok = false; } } if(ok) { - - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incomming.\n", client->num); - +#ifdef WS_SERVER_DEBUG + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINTLN("][handleHeader] Websocket connection incomming."); +#endif // generate Sec-WebSocket-Accept key - String sKey = acceptKey(client->cKey); - - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - sKey: %s\n", client->num, sKey.c_str()); - - client->status = WSC_CONNECTED; + String sKey = acceptKey(client.cKey); +#ifdef WS_SERVER_DEBUG + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINT("][handleHeader] - sKey: "); + WS_PRINTLN(sKey.c_str()); +#endif + client.status = WSC_CONNECTED; - client->tcp->write("HTTP/1.1 101 Switching Protocols\r\n" + client.tcp.write("HTTP/1.1 101 Switching Protocols\r\n" "Server: arduino-WebSocketsServer\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" "Sec-WebSocket-Version: 13\r\n" "Sec-WebSocket-Accept: "); - client->tcp->write(sKey.c_str(), sKey.length()); - client->tcp->write("\r\n"); + client.tcp.write(sKey.c_str(), sKey.length()); + client.tcp.write("\r\n"); - if(client->cProtocol.length() > 0) { + if(client.cProtocol.length() > 0) { // TODO add api to set Protocol of Server - client->tcp->write("Sec-WebSocket-Protocol: arduino\r\n"); + client.tcp.write("Sec-WebSocket-Protocol: arduino\r\n"); } // header end - client->tcp->write("\r\n"); + client.tcp.write("\r\n"); // send ping WebSockets::sendFrame(client, WSop_ping); - runCbEvent(client->num, WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length()); + runCbEvent(client.num, WStype_CONNECTED, (uint8_t *) client.cUrl.c_str(), client.cUrl.length()); } else { handleNonWebsocketConnection(client); } } } - - - diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index ebc76b2..3867d6a 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -28,8 +28,7 @@ #include #include "WebSockets.h" -#define WEBSOCKETS_SERVER_CLIENT_MAX (5) - +#define timeoutClient (uint32_t)120000 @@ -68,9 +67,9 @@ class WebSocketsServer: private WebSockets { void disconnect(void); void disconnect(uint8_t num); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +//#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) IPAddress remoteIP(uint8_t num); -#endif +//#endif protected: uint16_t _port; @@ -81,24 +80,28 @@ class WebSocketsServer: private WebSockets { WebSocketServerEvent _cbEvent; - void messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length); + void messageReceived(WSclient_t & client, WSopcode_t opcode, uint8_t * payload, size_t length); - void clientDisconnect(WSclient_t * client); - bool clientIsConnected(WSclient_t * client); + void clientDisconnect(WSclient_t & client); + bool clientIsConnected(WSclient_t & client); - void handleNewClients(void); - void handleClientData(void); + void handleNewClients(WSclient_t & client); + void handleClientData(WSclient_t & client); - void handleHeader(WSclient_t * client); + void handleHeader(WSclient_t & client); /** * called if a non Websocket connection is comming in. * Note: can be overrided * @param client WSclient_t * ptr to the client struct */ - virtual void handleNonWebsocketConnection(WSclient_t * client) { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] no Websocket connection close.\n", client->num); - client->tcp->write("HTTP/1.1 400 Bad Request\r\n" + virtual void handleNonWebsocketConnection(WSclient_t & client) { +#ifdef WS_SERVER_DEBUG + WS_PRINT("[WS-Server]["); + WS_PRINT(client.num); + WS_PRINTLN("][handleHeader] no Websocket connection close."); +#endif + client.tcp.write("HTTP/1.1 400 Bad Request\r\n" "Server: arduino-WebSocket-Server\r\n" "Content-Type: text/plain\r\n" "Content-Length: 32\r\n" @@ -108,7 +111,6 @@ class WebSocketsServer: private WebSockets { "This is a Websocket server only!"); clientDisconnect(client); } - /** * called for sending a Event to the app * @param num uint8_t @@ -121,9 +123,7 @@ class WebSocketsServer: private WebSockets { _cbEvent(num, type, payload, length); } } - +private: + uint32_t timeOutCounter = 0; }; - - - #endif /* WEBSOCKETSSERVER_H_ */