First steps to do async

This commit is contained in:
Markus Sattler
2016-01-23 16:27:02 +01:00
parent ece771a275
commit 57e30e0634
8 changed files with 435 additions and 206 deletions

View File

@ -30,9 +30,9 @@
extern "C" { extern "C" {
#ifdef CORE_HAS_LIBB64 #ifdef CORE_HAS_LIBB64
#include <libb64/cencode.h> #include <libb64/cencode.h>
#else #else
#include "libb64/cencode_inc.h" #include "libb64/cencode_inc.h"
#endif #endif
} }
@ -46,8 +46,6 @@ extern "C" {
#endif #endif
#define WEBSOCKETS_MAX_HEADER_SIZE (14)
/** /**
* *
* @param client WSclient_t * ptr to the client struct * @param client WSclient_t * ptr to the client struct
@ -120,7 +118,6 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay
headerSize += 4; headerSize += 4;
} }
#ifdef WEBSOCKETS_USE_BIG_MEM #ifdef WEBSOCKETS_USE_BIG_MEM
// only for ESP since AVR has less HEAP // only for ESP since AVR has less HEAP
// try to send data in one TCP package (only if some free Heap is there) // try to send data in one TCP package (only if some free Heap is there)
@ -161,22 +158,35 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay
} }
if(length < 126) { if(length < 126) {
*headerPtr |= length; headerPtr++; *headerPtr |= length;
headerPtr++;
} else if(length < 0xFFFF) { } else if(length < 0xFFFF) {
*headerPtr |= 126; headerPtr++; *headerPtr |= 126;
*headerPtr = ((length >> 8) & 0xFF); headerPtr++; headerPtr++;
*headerPtr = (length & 0xFF); headerPtr++; *headerPtr = ((length >> 8) & 0xFF);
headerPtr++;
*headerPtr = (length & 0xFF);
headerPtr++;
} else { } else {
// Normally we never get here (to less memory) // Normally we never get here (to less memory)
*headerPtr |= 127; headerPtr++; *headerPtr |= 127;
*headerPtr = 0x00; headerPtr++; headerPtr++;
*headerPtr = 0x00; headerPtr++; *headerPtr = 0x00;
*headerPtr = 0x00; headerPtr++; headerPtr++;
*headerPtr = 0x00; headerPtr++; *headerPtr = 0x00;
*headerPtr = ((length >> 24) & 0xFF); headerPtr++; headerPtr++;
*headerPtr = ((length >> 16) & 0xFF); headerPtr++; *headerPtr = 0x00;
*headerPtr = ((length >> 8) & 0xFF); headerPtr++; headerPtr++;
*headerPtr = (length & 0xFF); headerPtr++; *headerPtr = 0x00;
headerPtr++;
*headerPtr = ((length >> 24) & 0xFF);
headerPtr++;
*headerPtr = ((length >> 16) & 0xFF);
headerPtr++;
*headerPtr = ((length >> 8) & 0xFF);
headerPtr++;
*headerPtr = (length & 0xFF);
headerPtr++;
} }
if(mask) { if(mask) {
@ -185,7 +195,8 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay
// by this fact its possible the do the masking // by this fact its possible the do the masking
for(uint8_t x = 0; x < sizeof(maskKey); x++) { for(uint8_t x = 0; x < sizeof(maskKey); x++) {
maskKey[x] = random(0xFF); maskKey[x] = random(0xFF);
*headerPtr = maskKey[x]; headerPtr++; *headerPtr = maskKey[x];
headerPtr++;
} }
uint8_t * dataMaskPtr; uint8_t * dataMaskPtr;
@ -201,10 +212,14 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay
} }
} else { } else {
*headerPtr = maskKey[0]; headerPtr++; *headerPtr = maskKey[0];
*headerPtr = maskKey[1]; headerPtr++; headerPtr++;
*headerPtr = maskKey[2]; headerPtr++; *headerPtr = maskKey[1];
*headerPtr = maskKey[3]; headerPtr++; headerPtr++;
*headerPtr = maskKey[2];
headerPtr++;
*headerPtr = maskKey[3];
headerPtr++;
} }
} }
@ -237,154 +252,211 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay
} }
/**
* callen when HTTP header is done
* @param client WSclient_t * ptr to the client struct
*/
void WebSockets::headerDone(WSclient_t * client) {
client->status = WSC_CONNECTED;
client->cWsRXsize = 0;
DEBUG_WEBSOCKETS("[WS][%d][headerDone] Header Handling Done (%uus).\n", client->num);
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
client->cHttpLine = "";
handleWebsocket(client);
#endif
}
/** /**
* handle the WebSocket stream * handle the WebSocket stream
* @param client WSclient_t * ptr to the client struct * @param client WSclient_t * ptr to the client struct
*/ */
void WebSockets::handleWebsocket(WSclient_t * client) { void WebSockets::handleWebsocket(WSclient_t * client) {
if(client->cWsRXsize == 0) {
handleWebsocketCb(client);
}
}
uint8_t buffer[8] = { 0 }; /**
* wait for
* @param client
* @param size
*/
bool WebSockets::handleWebsocketWaitFor(WSclient_t * client, size_t size) {
if(size > WEBSOCKETS_MAX_HEADER_SIZE) {
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocketWaitFor] size: %d to big!\n", client->num, size);
return false;
}
bool fin; if(client->cWsRXsize >= size) {
bool rsv1; return true;
bool rsv2; }
bool rsv3;
WSopcode_t opCode;
bool mask;
size_t payloadLen;
uint8_t maskKey[4]; DEBUG_WEBSOCKETS("[WS][%d][handleWebsocketWaitFor] size: %d cWsRXsize: %d\n", client->num, size, client->cWsRXsize);
readCb(client, &client->cWsHeader[client->cWsRXsize], (size - client->cWsRXsize), std::bind([](WebSockets * server, size_t size, WSclient_t * client, bool ok) {
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocketWaitFor][readCb] size: %d ok: %d\n", client->num, size, ok);
if(ok) {
client->cWsRXsize = size;
server->handleWebsocketCb(client);
} else {
DEBUG_WEBSOCKETS("[WS][%d][readCb] failed.\n", client->num);
client->cWsRXsize = 0;
// timeout or error
server->clientDisconnect(client, 1002);
}
}, this, size, std::placeholders::_1, std::placeholders::_2));
return false;
}
void WebSockets::handleWebsocketCb(WSclient_t * client) {
uint8_t * buffer = client->cWsHeader;
WSMessageHeader_t * header = &client->cWsHeaderDecode;
uint8_t * payload = NULL; uint8_t * payload = NULL;
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] ------- read massage frame -------\n", client->num); uint8_t headerLen = 2;
if(!readWait(client, buffer, 2)) { if(!handleWebsocketWaitFor(client, headerLen)) {
//timeout
clientDisconnect(client, 1002);
return; return;
} }
// split first 2 bytes in the data // split first 2 bytes in the data
fin = ((buffer[0] >> 7) & 0x01); header->fin = ((*buffer >> 7) & 0x01);
rsv1 = ((buffer[0] >> 6) & 0x01); header->rsv1 = ((*buffer >> 6) & 0x01);
rsv2 = ((buffer[0] >> 5) & 0x01); header->rsv2 = ((*buffer >> 5) & 0x01);
rsv3 = ((buffer[0] >> 4) & 0x01); header->rsv3 = ((*buffer >> 4) & 0x01);
opCode = (WSopcode_t) (buffer[0] & 0x0F); header->opCode = (WSopcode_t) (*buffer & 0x0F);
buffer++;
mask = ((buffer[1] >> 7) & 0x01); header->mask = ((*buffer >> 7) & 0x01);
payloadLen = (WSopcode_t) (buffer[1] & 0x7F); header->payloadLen = (WSopcode_t) (*buffer & 0x7F);
buffer++;
if(payloadLen == 126) { if(header->payloadLen == 126) {
if(!readWait(client, buffer, 2)) { headerLen += 4;
//timeout if(!handleWebsocketWaitFor(client, headerLen)) {
clientDisconnect(client, 1002);
return; return;
} }
payloadLen = buffer[0] << 8 | buffer[1]; header->payloadLen = buffer[0] << 8 | buffer[1];
} else if(payloadLen == 127) { buffer += 2;
} else if(header->payloadLen == 127) {
headerLen += 8;
// read 64bit integer as length // read 64bit integer as length
if(!readWait(client, buffer, 8)) { if(!handleWebsocketWaitFor(client, headerLen)) {
//timeout
clientDisconnect(client, 1002);
return; return;
} }
if(buffer[0] != 0 || buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0) { if(buffer[0] != 0 || buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0) {
// really to big! // really to big!
payloadLen = 0xFFFFFFFF; header->payloadLen = 0xFFFFFFFF;
} else { } else {
payloadLen = buffer[4] << 24 | buffer[5] << 16 | buffer[6] << 8 | buffer[7]; header->payloadLen = buffer[4] << 24 | buffer[5] << 16 | buffer[6] << 8 | buffer[7];
} }
buffer += 8;
} }
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] ------- read massage frame -------\n", client->num);
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] mask: %u payloadLen: %u\n", client->num, mask, payloadLen); DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] fin: %u rsv1: %u rsv2: %u rsv3 %u opCode: %u\n", client->num, header->fin, header->rsv1, header->rsv2, header->rsv3, header->opCode);
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] mask: %u payloadLen: %u\n", client->num, header->mask, header->payloadLen);
if(payloadLen > WEBSOCKETS_MAX_DATA_SIZE) { if(header->payloadLen > WEBSOCKETS_MAX_DATA_SIZE) {
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] payload to big! (%u)\n", client->num, payloadLen); DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] payload to big! (%u)\n", client->num, header->payloadLen);
clientDisconnect(client, 1009); clientDisconnect(client, 1009);
return; return;
} }
if(mask) { if(header->mask) {
if(!readWait(client, maskKey, 4)) { headerLen += 4;
//timeout if(!handleWebsocketWaitFor(client, headerLen)) {
clientDisconnect(client, 1002);
return; return;
} }
header->maskKey = buffer;
buffer += 4;
} }
if(payloadLen > 0) { if(header->payloadLen > 0) {
// if text data we need one more // if text data we need one more
payload = (uint8_t *) malloc(payloadLen + 1); payload = (uint8_t *) malloc(header->payloadLen + 1);
if(!payload) { if(!payload) {
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] to less memory to handle payload %d!\n", client->num, payloadLen); DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] to less memory to handle payload %d!\n", client->num, header->payloadLen);
clientDisconnect(client, 1011); clientDisconnect(client, 1011);
return; return;
} }
readCb(client, payload, header->payloadLen, std::bind(&WebSockets::handleWebsocketPayloadCb, this, std::placeholders::_1, std::placeholders::_2, payload));
} else {
handleWebsocketPayloadCb(client, true, NULL);
}
}
if(!readWait(client, payload, payloadLen)) { void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * payload) {
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] missing data!\n", client->num); WSMessageHeader_t * header = &client->cWsHeaderDecode;
free(payload); if(ok) {
clientDisconnect(client, 1002); if(header->payloadLen > 0) {
return; payload[header->payloadLen] = 0x00;
}
payload[payloadLen] = 0x00; if(header->mask) {
//decode XOR
if(mask) { for(size_t i = 0; i < header->payloadLen; i++) {
//decode XOR payload[i] = (payload[i] ^ header->maskKey[i % 4]);
for(size_t i = 0; i < payloadLen; i++) { }
payload[i] = (payload[i] ^ maskKey[i % 4]);
} }
} }
}
switch(opCode) { switch(header->opCode) {
case WSop_text: case WSop_text:
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] text: %s\n", client->num, payload); DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] text: %s\n", client->num, payload);
// no break here! // no break here!
case WSop_binary: case WSop_binary:
messageRecived(client, opCode, payload, payloadLen); messageRecived(client, header->opCode, payload, header->payloadLen);
break; break;
case WSop_ping: case WSop_ping:
// send pong back // send pong back
sendFrame(client, WSop_pong, payload, payloadLen); sendFrame(client, WSop_pong, payload, header->payloadLen);
break; break;
case WSop_pong: case WSop_pong:
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload); DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload);
break; break;
case WSop_close: case WSop_close: {
{
uint16_t reasonCode = 1000; uint16_t reasonCode = 1000;
if(payloadLen >= 2) { if(header->payloadLen >= 2) {
reasonCode = payload[0] << 8 | payload[1]; reasonCode = payload[0] << 8 | payload[1];
} }
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get ask for close. Code: %d", client->num, reasonCode); DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get ask for close. Code: %d", client->num, reasonCode);
if(payloadLen > 2) { if(header->payloadLen > 2) {
DEBUG_WEBSOCKETS(" (%s)\n", (payload+2)); DEBUG_WEBSOCKETS(" (%s)\n", (payload + 2));
} else { } else {
DEBUG_WEBSOCKETS("\n"); DEBUG_WEBSOCKETS("\n");
} }
clientDisconnect(client, 1000); clientDisconnect(client, 1000);
} }
break; break;
case WSop_continuation: case WSop_continuation:
// continuation is not supported // continuation is not supported
clientDisconnect(client, 1003); clientDisconnect(client, 1003);
break; break;
default: default:
clientDisconnect(client, 1002); clientDisconnect(client, 1002);
break; break;
} }
if(payload) { if(payload) {
free(payload);
}
// reset input
client->cWsRXsize = 0;
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
//register callback for next message
handleWebsocketWaitFor(client, 2);
#endif
} else {
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] missing data!\n", client->num);
free(payload); free(payload);
clientDisconnect(client, 1002);
} }
} }
/** /**
@ -417,7 +489,7 @@ String WebSockets::acceptKey(String clientKey) {
* @return base64 encoded String * @return base64 encoded String
*/ */
String WebSockets::base64_encode(uint8_t * data, size_t length) { String WebSockets::base64_encode(uint8_t * data, size_t length) {
size_t size = ((length*1.6f)+1); size_t size = ((length * 1.6f) + 1);
char * buffer = (char *) malloc(size); char * buffer = (char *) malloc(size);
if(buffer) { if(buffer) {
base64_encodestate _state; base64_encodestate _state;
@ -439,28 +511,46 @@ String WebSockets::base64_encode(uint8_t * data, size_t length) {
* @param n size_t byte count * @param n size_t byte count
* @return true if ok * @return true if ok
*/ */
bool WebSockets::readWait(WSclient_t * client, uint8_t *out, size_t n) { bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWaitCb cb) {
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
client->tcp->readBytes(out, n, std::bind([](WSclient_t * client, bool ok, WSreadWaitCb cb) {
if(cb) {
cb(client, ok);
}
}, client, std::placeholders::_1, cb));
#else
unsigned long t = millis(); unsigned long t = millis();
size_t len; size_t len;
DEBUG_WEBSOCKETS("[readCb] n: %d t: %d\n", n, t);
while(n > 0) { while(n > 0) {
if(!client->tcp) { if(client->tcp == NULL) {
DEBUG_WEBSOCKETS("[readWait] tcp is null!\n"); DEBUG_WEBSOCKETS("[readCb] tcp is null!\n");
if(cb) {
cb(client, false);
}
return false; return false;
} }
if(!client->tcp->connected()) { if(!client->tcp->connected()) {
DEBUG_WEBSOCKETS("[readWait] not connected!\n"); DEBUG_WEBSOCKETS("[readCb] not connected!\n");
if(cb) {
cb(client, false);
}
return false; return false;
} }
if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) { if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) {
DEBUG_WEBSOCKETS("[readWait] receive TIMEOUT!\n"); DEBUG_WEBSOCKETS("[readCb] receive TIMEOUT! %d\n", (millis() - t));
if(cb) {
cb(client, false);
}
return false; return false;
} }
if(!client->tcp->available()) { if(!client->tcp->available()) {
#ifdef ESP8266 #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
delay(0); delay(0);
#endif #endif
continue; continue;
@ -475,9 +565,14 @@ bool WebSockets::readWait(WSclient_t * client, uint8_t *out, size_t n) {
} else { } else {
//DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n); //DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n);
} }
#ifdef ESP8266 #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
delay(0); delay(0);
#endif #endif
} }
if(cb) {
cb(client, true);
}
#endif
return true; return true;
} }

View File

@ -27,7 +27,7 @@
#include <Arduino.h> #include <Arduino.h>
//#define DEBUG_WEBSOCKETS(...) Serial1.printf( __VA_ARGS__ ) //#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ )
#ifndef DEBUG_WEBSOCKETS #ifndef DEBUG_WEBSOCKETS
#define DEBUG_WEBSOCKETS(...) #define DEBUG_WEBSOCKETS(...)
@ -44,20 +44,39 @@
#define WEBSOCKETS_TCP_TIMEOUT (1500) #define WEBSOCKETS_TCP_TIMEOUT (1500)
#define NETWORK_ESP8266 (1) #define NETWORK_ESP8266_ASYNC (0)
#define NETWORK_W5100 (2) #define NETWORK_ESP8266 (1)
#define NETWORK_ENC28J60 (3) #define NETWORK_W5100 (2)
#define NETWORK_ENC28J60 (3)
// max size of the WS Message Header
#define WEBSOCKETS_MAX_HEADER_SIZE (14)
// select Network type based // select Network type based
#ifdef ESP8266 #ifdef ESP8266
#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 //#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266
#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266_ASYNC
#else #else
#define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 #define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100
#endif #endif
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) // Note:
// No SSL/WSS support for client in Async mode
// TLS lib need a sync interface!
#ifndef ESP8266
#error "network type ESP8266 ASYNC only possible on the ESP mcu!"
#endif
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncTCPbuffer.h>
#define WEBSOCKETS_NETWORK_CLASS AsyncTCPbuffer
#define WEBSOCKETS_NETWORK_SERVER_CLASS AsyncServer
#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
#ifndef ESP8266 #ifndef ESP8266
#error "network type ESP8266 only possible on the ESP mcu!" #error "network type ESP8266 only possible on the ESP mcu!"
@ -110,6 +129,21 @@ typedef enum {
///< %xB-F are reserved for further control frames ///< %xB-F are reserved for further control frames
} WSopcode_t; } WSopcode_t;
typedef struct {
bool fin;
bool rsv1;
bool rsv2;
bool rsv3;
WSopcode_t opCode;
bool mask;
size_t payloadLen;
uint8_t * maskKey;
} WSMessageHeader_t;
typedef struct { typedef struct {
uint8_t num; ///< connection number uint8_t num; ///< connection number
@ -134,10 +168,23 @@ typedef struct {
String cExtensions; ///< client Sec-WebSocket-Extensions String cExtensions; ///< client Sec-WebSocket-Extensions
uint16_t cVersion; ///< client Sec-WebSocket-Version uint16_t cVersion; ///< client Sec-WebSocket-Version
uint8_t cWsRXsize; ///< State of the RX
uint8_t cWsHeader[WEBSOCKETS_MAX_HEADER_SIZE]; ///< RX WS Message buffer
WSMessageHeader_t cWsHeaderDecode;
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
String cHttpLine; ///< HTTP header lines
#endif
} WSclient_t; } WSclient_t;
class WebSockets { class WebSockets {
protected: protected:
typedef std::function<void(WSclient_t * client, bool ok)> WSreadWaitCb;
virtual void clientDisconnect(WSclient_t * client); virtual void clientDisconnect(WSclient_t * client);
virtual bool clientIsConnected(WSclient_t * client); virtual bool clientIsConnected(WSclient_t * client);
@ -146,14 +193,20 @@ class WebSockets {
void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0); 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 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 headerDone(WSclient_t * client);
void handleWebsocket(WSclient_t * client); void handleWebsocket(WSclient_t * client);
bool readWait(WSclient_t * client, uint8_t *out, size_t n); bool handleWebsocketWaitFor(WSclient_t * client, size_t size);
void handleWebsocketCb(WSclient_t * client);
void handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * payload);
String acceptKey(String clientKey); String acceptKey(String clientKey);
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);
}; };
#endif /* WEBSOCKETS_H_ */ #endif /* WEBSOCKETS_H_ */

View File

@ -40,7 +40,9 @@ WebSocketsClient::~WebSocketsClient() {
void WebSocketsClient::begin(const char *host, uint16_t port, const char * url) { void WebSocketsClient::begin(const char *host, uint16_t port, const char * url) {
_host = host; _host = host;
_port = port; _port = port;
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
_fingerprint = ""; _fingerprint = "";
#endif
_client.num = 0; _client.num = 0;
_client.status = WSC_NOT_CONNECTED; _client.status = WSC_NOT_CONNECTED;
@ -141,10 +143,12 @@ void WebSocketsClient::loop(void) {
} else { } else {
DEBUG_WEBSOCKETS("[WS-Client] connection to %s:%u Faild\n", _host.c_str(), _port); DEBUG_WEBSOCKETS("[WS-Client] connection to %s:%u Faild\n", _host.c_str(), _port);
delay(10); //some litle delay to not flood the server delay(10); //some little delay to not flood the server
} }
} else { } else {
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
handleClientData(); handleClientData();
#endif
} }
} }
@ -248,12 +252,15 @@ void WebSocketsClient::messageRecived(WSclient_t * client, WSopcode_t opcode, ui
*/ */
void WebSocketsClient::clientDisconnect(WSclient_t * client) { void WebSocketsClient::clientDisconnect(WSclient_t * client) {
bool event = false;
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
if(client->isSSL && client->ssl) { if(client->isSSL && client->ssl) {
if(client->ssl->connected()) { if(client->ssl->connected()) {
client->ssl->flush(); client->ssl->flush();
client->ssl->stop(); client->ssl->stop();
} }
event = true;
delete client->ssl; delete client->ssl;
client->ssl = NULL; client->ssl = NULL;
client->tcp = NULL; client->tcp = NULL;
@ -265,6 +272,7 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) {
client->tcp->flush(); client->tcp->flush();
client->tcp->stop(); client->tcp->stop();
} }
event = true;
delete client->tcp; delete client->tcp;
client->tcp = NULL; client->tcp = NULL;
} }
@ -280,9 +288,9 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) {
client->status = WSC_NOT_CONNECTED; client->status = WSC_NOT_CONNECTED;
DEBUG_WEBSOCKETS("[WS-Client] client disconnected.\n"); DEBUG_WEBSOCKETS("[WS-Client] client disconnected.\n");
if(event) {
runCbEvent(WStype_DISCONNECTED, NULL, 0); runCbEvent(WStype_DISCONNECTED, NULL, 0);
}
} }
/** /**
@ -316,7 +324,7 @@ bool WebSocketsClient::clientIsConnected(WSclient_t * client) {
return false; return false;
} }
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
/** /**
* Handel incomming data from Client * Handel incomming data from Client
*/ */
@ -325,7 +333,10 @@ void WebSocketsClient::handleClientData(void) {
if(len > 0) { if(len > 0) {
switch(_client.status) { switch(_client.status) {
case WSC_HEADER: case WSC_HEADER:
handleHeader(&_client); {
String headerLine = _client->tcp->readStringUntil('\n');
handleHeader(&_client, &headerLine);
}
break; break;
case WSC_CONNECTED: case WSC_CONNECTED:
WebSockets::handleWebsocket(&_client); WebSockets::handleWebsocket(&_client);
@ -335,10 +346,11 @@ void WebSocketsClient::handleClientData(void) {
break; break;
} }
} }
#ifdef ESP8266 #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
delay(0); delay(0);
#endif #endif
} }
#endif
/** /**
* send the WebSocket header to Server * send the WebSocket header to Server
@ -377,6 +389,10 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
client->tcp->write(handshake.c_str(), handshake.length()); client->tcp->write(handshake.c_str(), handshake.length());
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine)));
#endif
DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header... Done (%uus).\n", (micros() - start)); DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header... Done (%uus).\n", (micros() - start));
} }
@ -385,20 +401,19 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
* handle the WebSocket header reading * handle the WebSocket header reading
* @param client WSclient_t * ptr to the client struct * @param client WSclient_t * ptr to the client struct
*/ */
void WebSocketsClient::handleHeader(WSclient_t * client) { void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
String headerLine = client->tcp->readStringUntil('\n'); headerLine->trim(); // remove \r
headerLine.trim(); // remove \r
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());
if(headerLine.startsWith("HTTP/1.")) { if(headerLine->startsWith("HTTP/1.")) {
// "HTTP/1.1 101 Switching Protocols" // "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(':')) { } else if(headerLine->indexOf(':')) {
String headerName = headerLine.substring(0, headerLine.indexOf(':')); String headerName = headerLine->substring(0, headerLine->indexOf(':'));
String headerValue = headerLine.substring(headerLine.indexOf(':') + 2); String headerValue = headerLine->substring(headerLine->indexOf(':') + 2);
if(headerName.equalsIgnoreCase("Connection")) { if(headerName.equalsIgnoreCase("Connection")) {
if(headerValue.indexOf("Upgrade") >= 0) { if(headerValue.indexOf("Upgrade") >= 0) {
@ -419,9 +434,14 @@ void WebSocketsClient::handleHeader(WSclient_t * client) {
client->cVersion = headerValue.toInt(); client->cVersion = headerValue.toInt();
} }
} else { } else {
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine.c_str()); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str());
} }
(*headerLine) = "";
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine)));
#endif
} else { } else {
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header read fin.\n"); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header read fin.\n");
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Client settings:\n"); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Client settings:\n");
@ -456,6 +476,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client) {
} }
if(ok) { if(ok) {
if(client->cAccept.length() == 0) { if(client->cAccept.length() == 0) {
ok = false; ok = false;
} else { } else {
@ -471,8 +492,8 @@ void WebSocketsClient::handleHeader(WSclient_t * client) {
if(ok) { if(ok) {
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Websocket connection init done.\n"); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Websocket connection init done.\n");
headerDone(client);
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());

View File

@ -75,11 +75,12 @@ class WebSocketsClient: private WebSockets {
void clientDisconnect(WSclient_t * client); void clientDisconnect(WSclient_t * client);
bool clientIsConnected(WSclient_t * client); bool clientIsConnected(WSclient_t * client);
void handleNewClients(void); #if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
void handleClientData(void); void handleClientData(void);
#endif
void sendHeader(WSclient_t * client); void sendHeader(WSclient_t * client);
void handleHeader(WSclient_t * client); void handleHeader(WSclient_t * client, String * headerLine);
/** /**
* called for sending a Event to the app * called for sending a Event to the app

View File

@ -32,10 +32,17 @@ WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol
_server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port); _server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port);
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
_server->onClient([](void *s, AsyncClient* c){
((WebSocketsServer*)s)->newClient(new AsyncTCPbuffer(c));
}, this);
#endif
_cbEvent = NULL; _cbEvent = NULL;
} }
WebSocketsServer::~WebSocketsServer() { WebSocketsServer::~WebSocketsServer() {
// disconnect all clients // disconnect all clients
disconnect(); disconnect();
@ -72,6 +79,11 @@ void WebSocketsServer::begin(void) {
client->cVersion = 0; client->cVersion = 0;
client->cIsUpgrade = false; client->cIsUpgrade = false;
client->cIsWebsocket = false; client->cIsWebsocket = false;
client->cWsRXsize = 0;
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
client->cHttpLine = "";
#endif
} }
#ifdef ESP8266 #ifdef ESP8266
@ -90,8 +102,10 @@ void WebSocketsServer::begin(void) {
* called in arduino loop * called in arduino loop
*/ */
void WebSocketsServer::loop(void) { void WebSocketsServer::loop(void) {
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
handleNewClients(); handleNewClients();
handleClientData(); handleClientData();
#endif
} }
/** /**
@ -155,7 +169,7 @@ void WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool heade
if(clientIsConnected(client)) { if(clientIsConnected(client)) {
sendFrame(client, WSop_text, payload, length, false, true, headerToPayload); sendFrame(client, WSop_text, payload, length, false, true, headerToPayload);
} }
#ifdef ESP8266 #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
delay(0); delay(0);
#endif #endif
} }
@ -211,7 +225,7 @@ void WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool heade
if(clientIsConnected(client)) { if(clientIsConnected(client)) {
sendFrame(client, WSop_binary, payload, length, false, true, headerToPayload); sendFrame(client, WSop_binary, payload, length, false, true, headerToPayload);
} }
#ifdef ESP8266 #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
delay(0); delay(0);
#endif #endif
} }
@ -248,7 +262,7 @@ void WebSocketsServer::disconnect(uint8_t num) {
} }
} }
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
/** /**
* get an IP for a client * get an IP for a client
* @param num uint8_t client id * @param num uint8_t client id
@ -270,6 +284,48 @@ IPAddress WebSocketsServer::remoteIP(uint8_t num) {
//################################################################################# //#################################################################################
//################################################################################# //#################################################################################
/**
* handle new client connection
* @param client
*/
bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) {
WSclient_t * client;
// search free list entry for client
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
client = &_clients[i];
// state is not connected or tcp connection is lost
if(!clientIsConnected(client)) {
client->tcp = TCPclient;
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
client->isSSL = false;
client->tcp->setNoDelay(true);
#endif
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
// set Timeout for readBytesUntil and readStringUntil
client->tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT);
#endif
client->status = WSC_HEADER;
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
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);
#endif
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine)));
#endif
return true;
break;
}
}
return false;
}
/** /**
* *
* @param client WSclient_t * ptr to the client struct * @param client WSclient_t * ptr to the client struct
@ -314,7 +370,9 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) {
if(client->tcp) { if(client->tcp) {
if(client->tcp->connected()) { if(client->tcp->connected()) {
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
client->tcp->flush(); client->tcp->flush();
#endif
client->tcp->stop(); client->tcp->stop();
} }
delete client->tcp; delete client->tcp;
@ -328,6 +386,11 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) {
client->cIsUpgrade = false; client->cIsUpgrade = false;
client->cIsWebsocket = false; client->cIsWebsocket = false;
client->cWsRXsize = 0;
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
client->cHttpLine = "";
#endif
client->status = WSC_NOT_CONNECTED; client->status = WSC_NOT_CONNECTED;
DEBUG_WEBSOCKETS("[WS-Server][%d] client disconnected.\n", client->num); DEBUG_WEBSOCKETS("[WS-Server][%d] client disconnected.\n", client->num);
@ -367,71 +430,50 @@ bool WebSocketsServer::clientIsConnected(WSclient_t * client) {
return false; return false;
} }
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
/** /**
* Handle incomming Connection Request * Handle incomming Connection Request
*/ */
void WebSocketsServer::handleNewClients(void) { void WebSocketsServer::handleNewClients(void) {
WSclient_t * client;
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
while(_server->hasClient()) { while(_server->hasClient()) {
#endif #endif
bool ok = false; bool ok = false;
// search free list entry for client
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
client = &_clients[i];
// 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());
#endif
if(!client->tcp) {
DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!");
return;
}
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
client->isSSL = false; // store new connection
client->tcp->setNoDelay(true); WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available());
#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 #else
DEBUG_WEBSOCKETS("[WS-Server][%d] new client\n", client->num); WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available());
#endif #endif
ok = true;
break; if(!tcpClient) {
} DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!");
return;
} }
ok = newClient(tcpClient);
if(!ok) { if(!ok) {
// no free space to handle client // no free space to handle client
WEBSOCKETS_NETWORK_CLASS tcpClient = _server->available();
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
IPAddress ip = client->tcp->remoteIP(); IPAddress ip = tcpClient->remoteIP();
DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
#else #else
DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n"); DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n");
#endif #endif
tcpClient.stop(); tcpClient->stop();
} }
#ifdef ESP8266
delay(0);
#endif
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
delay(0);
} }
#endif #endif
} }
/** /**
* Handel incomming data from Client * Handel incomming data from Client
*/ */
@ -443,10 +485,13 @@ void WebSocketsServer::handleClientData(void) {
if(clientIsConnected(client)) { if(clientIsConnected(client)) {
int len = client->tcp->available(); int len = client->tcp->available();
if(len > 0) { if(len > 0) {
//DEBUG_WEBSOCKETS("[WS-Server][%d][handleClientData] len: %d\n", client->num, len);
switch(client->status) { switch(client->status) {
case WSC_HEADER: case WSC_HEADER:
handleHeader(client); {
String headerLine = client->tcp->readStringUntil('\n');
handleHeader(client, &headerLine);
}
break; break;
case WSC_CONNECTED: case WSC_CONNECTED:
WebSockets::handleWebsocket(client); WebSockets::handleWebsocket(client);
@ -457,31 +502,32 @@ void WebSocketsServer::handleClientData(void) {
} }
} }
} }
#ifdef ESP8266 #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
delay(0); delay(0);
#endif #endif
} }
} }
#endif
/** /**
* handle the WebSocket header reading * handle the WebSocket header reading
* @param client WSclient_t * ptr to the client struct * @param client WSclient_t * ptr to the client struct
*/ */
void WebSocketsServer::handleHeader(WSclient_t * client) { void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
String headerLine = client->tcp->readStringUntil('\n'); headerLine->trim(); // remove \r
headerLine.trim(); // remove \r
if(headerLine.length() > 0) { if(headerLine->length() > 0) {
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine.c_str()); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine->c_str());
// websocket request starts allways with GET see rfc6455 // websocket request starts allways with GET see rfc6455
if(headerLine.startsWith("GET ")) { if(headerLine->startsWith("GET ")) {
// cut URL out // cut URL out
client->cUrl = headerLine.substring(4, headerLine.indexOf(' ', 4)); client->cUrl = headerLine->substring(4, headerLine->indexOf(' ', 4));
} else if(headerLine.indexOf(':')) { } else if(headerLine->indexOf(':')) {
String headerName = headerLine.substring(0, headerLine.indexOf(':')); String headerName = headerLine->substring(0, headerLine->indexOf(':'));
String headerValue = headerLine.substring(headerLine.indexOf(':') + 2); String headerValue = headerLine->substring(headerLine->indexOf(':') + 2);
if(headerName.equalsIgnoreCase("Connection")) { if(headerName.equalsIgnoreCase("Connection")) {
if(headerValue.indexOf("Upgrade") >= 0) { if(headerValue.indexOf("Upgrade") >= 0) {
@ -502,9 +548,13 @@ void WebSocketsServer::handleHeader(WSclient_t * client) {
client->cExtensions = headerValue; client->cExtensions = headerValue;
} }
} else { } else {
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine.c_str()); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str());
} }
(*headerLine) = "";
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine)));
#endif
} else { } else {
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Header read fin.\n", client->num); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Header read fin.\n", client->num);
@ -532,7 +582,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client) {
if(ok) { if(ok) {
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incomming.\n", client->num); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incoming.\n", client->num);
// generate Sec-WebSocket-Accept key // generate Sec-WebSocket-Accept key
String sKey = acceptKey(client->cKey); String sKey = acceptKey(client->cKey);
@ -568,6 +618,8 @@ void WebSocketsServer::handleHeader(WSclient_t * client) {
// header end // header end
client->tcp->write("\r\n"); client->tcp->write("\r\n");
headerDone(client);
// send ping // send ping
WebSockets::sendFrame(client, WSop_ping); WebSockets::sendFrame(client, WSop_ping);

View File

@ -68,7 +68,7 @@ public:
void disconnect(void); void disconnect(void);
void disconnect(uint8_t num); void disconnect(uint8_t num);
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
IPAddress remoteIP(uint8_t num); IPAddress remoteIP(uint8_t num);
#endif #endif
@ -83,15 +83,20 @@ protected:
WebSocketServerEvent _cbEvent; WebSocketServerEvent _cbEvent;
bool newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient);
void messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length); void messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length);
void clientDisconnect(WSclient_t * client); void clientDisconnect(WSclient_t * client);
bool clientIsConnected(WSclient_t * client); bool clientIsConnected(WSclient_t * client);
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
void handleNewClients(void); void handleNewClients(void);
void handleClientData(void); void handleClientData(void);
#endif
void handleHeader(WSclient_t * client, String * headerLine);
void handleHeader(WSclient_t * client);
/** /**
* called if a non Websocket connection is comming in. * called if a non Websocket connection is comming in.

View File

@ -8,10 +8,11 @@ connection.onopen = function () {
connection.send('Message from Browser to ESP8266 yay its Working!! ' + new Date()); connection.send('Message from Browser to ESP8266 yay its Working!! ' + new Date());
connection.send('ping'); connection.send('ping');
setInterval(function() { /* setInterval(function() {
connection.send('Time: ' + new Date()); connection.send('Time: ' + new Date());
}, 20); }, 20);
*/
connection.send('Time: ' + new Date());
}; };
connection.onerror = function (error) { connection.onerror = function (error) {
@ -20,6 +21,7 @@ connection.onerror = function (error) {
connection.onmessage = function (e) { connection.onmessage = function (e) {
console.log('Server: ', e.data); console.log('Server: ', e.data);
connection.send('Time: ' + new Date());
}; };
function sendRGB() { function sendRGB() {

View File

@ -41,11 +41,11 @@ wsServer.on('request', function(request) {
connection.on('message', function(message) { connection.on('message', function(message) {
if (message.type === 'utf8') { if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data); console.log('Received Message: ' + message.utf8Data);
connection.sendUTF(message.utf8Data); // connection.sendUTF(message.utf8Data);
} }
else if (message.type === 'binary') { else if (message.type === 'binary') {
console.log('Received Binary Message of ' + message.binaryData.length + ' bytes'); console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
connection.sendBytes(message.binaryData); //connection.sendBytes(message.binaryData);
} }
}); });