speed up connection handling

note: dont use print on tcp! to slow! (17sec vs 78ms)

use client ptr as parameter for the most functions
This commit is contained in:
Markus Sattler
2015-05-22 14:40:46 +02:00
parent 02da0e0aa7
commit d63e8fdafb
2 changed files with 43 additions and 44 deletions

View File

@ -40,6 +40,7 @@ void WebSocketsServer::begin(void) {
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
client = &_clients[i]; client = &_clients[i];
client->num = i;
client->cUrl = ""; client->cUrl = "";
client->cKey = ""; client->cKey = "";
client->cProtocol = ""; client->cProtocol = "";
@ -71,25 +72,24 @@ void WebSocketsServer::loop(void) {
* Disconnect an client * Disconnect an client
* @param num uint8_t index of _clients array * @param num uint8_t index of _clients array
*/ */
void WebSocketsServer::clientDisconnect(uint8_t num) { void WebSocketsServer::clientDisconnect(WSclients_t * client) {
WSclients_t * client = &_clients[num];
if(client->tcp) { if(client->tcp) {
client->tcp.stop(); client->tcp.stop();
} }
/*
client->cUrl = "";
client->cKey = "";
client->cProtocol = "";
client->cVersion = 0;
client->cIsUpgrade = false;
client->cIsWebsocket = false;
client->sKey = ""; client->cUrl = "";
*/ client->cKey = "";
client->cProtocol = "";
client->cVersion = 0;
client->cIsUpgrade = false;
client->cIsWebsocket = false;
client->sKey = "";
client->status = WSC_NOT_CONNECTED; client->status = WSC_NOT_CONNECTED;
DEBUG_WEBSOCKETS("[WS-Server][%d] client disconnected.\n", num); DEBUG_WEBSOCKETS("[WS-Server][%d] client disconnected.\n", client->num);
} }
@ -98,8 +98,7 @@ void WebSocketsServer::clientDisconnect(uint8_t num) {
* @param num uint8_t index of _clients array * @param num uint8_t index of _clients array
* @return true = conneted * @return true = conneted
*/ */
bool WebSocketsServer::clientIsConnected(uint8_t num) { bool WebSocketsServer::clientIsConnected(WSclients_t * client) {
WSclients_t * client = &_clients[num];
if(client->status != WSC_NOT_CONNECTED && client->tcp.connected()) { if(client->status != WSC_NOT_CONNECTED && client->tcp.connected()) {
return true; return true;
@ -107,7 +106,7 @@ bool WebSocketsServer::clientIsConnected(uint8_t num) {
if(client->status != WSC_NOT_CONNECTED) { if(client->status != WSC_NOT_CONNECTED) {
// cleanup // cleanup
clientDisconnect(num); clientDisconnect(client);
} }
return false; return false;
} }
@ -124,17 +123,17 @@ void WebSocketsServer::handleNewClients(void) {
client = &_clients[i]; client = &_clients[i];
// state is not connected or tcp connection is lost // state is not connected or tcp connection is lost
if(!clientIsConnected(i)) { if(!clientIsConnected(client)) {
// store new connection // store new connection
client->tcp = _server->available(); client->tcp = _server->available();
client->tcp.setNoDelay(true);
// set Timeout for readBytesUntil and readStringUntil // set Timeout for readBytesUntil and readStringUntil
client->tcp.setTimeout(1000); client->tcp.setTimeout(1000);
client->status = WSC_HEADER; client->status = WSC_HEADER;
IPAddress ip = client->tcp.remoteIP(); IPAddress ip = client->tcp.remoteIP();
DEBUG_WEBSOCKETS("[WS-Server][%d] new client from %d.%d.%d.%d\n", i, ip[0], ip[1], ip[2], ip[3]); DEBUG_WEBSOCKETS("[WS-Server][%d] new client from %d.%d.%d.%d\n", client->num, ip[0], ip[1], ip[2], ip[3]);
ok = true; ok = true;
break; break;
} }
@ -159,19 +158,19 @@ void WebSocketsServer::handleClientData(void) {
WSclients_t * client; WSclients_t * client;
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
if(clientIsConnected(i)) { client = &_clients[i];
client = &_clients[i]; if(clientIsConnected(client)) {
int len = client->tcp.available(); int len = client->tcp.available();
if(len > 0) { if(len > 0) {
switch(client->status) { switch(client->status) {
case WSC_HEADER: case WSC_HEADER:
handleHeader(i); handleHeader(client);
break; break;
case WSC_CONNECTED: case WSC_CONNECTED:
break; break;
default: default:
clientDisconnect(i); clientDisconnect(client);
break; break;
} }
} }
@ -204,15 +203,14 @@ void WebSocketsServer::handleClientData(void) {
* handle the WebSocket headder reading * handle the WebSocket headder reading
* @param num uint8_t index of _clients array * @param num uint8_t index of _clients array
*/ */
void WebSocketsServer::handleHeader(uint8_t num) { void WebSocketsServer::handleHeader(WSclients_t * client) {
WSclients_t * client = &_clients[num];
String headerLine = client->tcp.readStringUntil('\n'); 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", num, headerLine.c_str()); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine.c_str());
// websocket request starts allway with GET see rfc6455 // websocket request starts allway with GET see rfc6455
if(headerLine.startsWith("GET ")) { if(headerLine.startsWith("GET ")) {
@ -237,15 +235,15 @@ void WebSocketsServer::handleHeader(uint8_t num) {
} }
} else { } else {
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Header read fin.\n", num); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Header read fin.\n", client->num);
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cURL: %s\n", num, client->cUrl.c_str()); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cURL: %s\n", client->num, client->cUrl.c_str());
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cIsUpgrade: %d\n", num, client->cIsUpgrade); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cIsUpgrade: %d\n", client->num, client->cIsUpgrade);
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cIsWebsocket: %d\n", num, client->cIsWebsocket); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cIsWebsocket: %d\n", client->num, client->cIsWebsocket);
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cKey: %s\n", num, client->cKey.c_str()); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cKey: %s\n", client->num, client->cKey.c_str());
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cProtocol: %s\n", num, client->cProtocol.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", num, client->cExtensions.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", num, client->cVersion); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cVersion: %d\n", client->num, client->cVersion);
bool ok = (client->cIsUpgrade && client->cIsWebsocket); bool ok = (client->cIsUpgrade && client->cIsWebsocket);
@ -256,14 +254,14 @@ void WebSocketsServer::handleHeader(uint8_t num) {
if(client->cKey.length() == 0) { if(client->cKey.length() == 0) {
ok = false; ok = false;
} }
if(client->cVersion == 0) { if(client->cVersion != 13) {
ok = false; ok = false;
} }
} }
if(ok) { if(ok) {
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incomming.\n", num); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incomming.\n", client->num);
//todo generate server key //todo generate server key
@ -271,18 +269,17 @@ void WebSocketsServer::handleHeader(uint8_t num) {
//client->status = WSC_CONNECTED; //client->status = WSC_CONNECTED;
} else { } else {
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] no Websocket connection close.\n", num); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] no Websocket connection close.\n", client->num);
client->tcp.print(F("HTTP/1.1 400 Bad Request\r\n" client->tcp.write("HTTP/1.1 400 Bad Request\r\n"
"Server: ESP8266-WebSocketsServer\r\n" "Server: ESP8266-WebSocketsServer\r\n"
"Content-Type: text/plain\r\n" "Content-Type: text/plain\r\n"
"Content-Length: 32\r\n" "Content-Length: 32\r\n"
"Connection: close\r\n" "Connection: close\r\n"
"Sec-WebSocket-Version: 13\r\n" "Sec-WebSocket-Version: 13\r\n"
"\r\n" "\r\n"
"This is a Websocket server only!")); "This is a Websocket server only!");
clientDisconnect(num); clientDisconnect(client);
} }
} }
} }

View File

@ -48,6 +48,8 @@ typedef enum {
} WSclientsStatus_t; } WSclientsStatus_t;
typedef struct { typedef struct {
uint8_t num; ///< connection number
WSclientsStatus_t status; WSclientsStatus_t status;
#ifdef ESP8266 #ifdef ESP8266
WiFiClient tcp; WiFiClient tcp;
@ -96,13 +98,13 @@ private:
WSclients_t _clients[WEBSOCKETS_SERVER_CLIENT_MAX]; WSclients_t _clients[WEBSOCKETS_SERVER_CLIENT_MAX];
void clientDisconnect(uint8_t num); void clientDisconnect(WSclients_t * client);
bool clientIsConnected(uint8_t num); bool clientIsConnected(WSclients_t * client);
void handleNewClients(void); void handleNewClients(void);
void handleClientData(void); void handleClientData(void);
void handleHeader(uint8_t num); void handleHeader(WSclients_t * client);
}; };