8000 First steps to do async · ServoDroid/arduinoWebSockets@57e30e0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 57e30e0

Browse files
committed
First steps to do async
1 parent ece771a commit 57e30e0

File tree

8 files changed

+436
-207
lines changed

8 files changed

+436
-207
lines changed

src/WebSockets.cpp

Lines changed: 214 additions & 119 deletions
Large diffs are not rendered by default.

src/WebSockets.h

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
#include <Arduino.h>
2929

30-
//#define DEBUG_WEBSOCKETS(...) Serial1.printf( __VA_ARGS__ )
30+
//#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ )
3131

3232
#ifndef DEBUG_WEBSOCKETS
3333
#define DEBUG_WEBSOCKETS(...)
@@ -44,20 +44,39 @@
4444

4545
#define WEBSOCKETS_TCP_TIMEOUT (1500)
4646

47-
#define NETWORK_ESP8266 (1)
48-
#define NETWORK_W5100 (2)
49-
#define NETWORK_ENC28J60 (3)
47+
#define NETWORK_ESP8266_ASYNC (0)
48+
#define NETWORK_ESP8266 (1)
49+
#define NETWORK_W5100 (2)
50+
#define NETWORK_ENC28J60 (3)
5051

52+
// max size of the WS Message Header
53+
#define WEBSOCKETS_MAX_HEADER_SIZE (14)
5154

5255
// select Network type based
5356
#ifdef ESP8266
54-
#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266
57+
//#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266
58+
#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266_ASYNC
5559
#else
5660
#define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100
5761
#endif
5862

63+
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
5964

60-
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
65+
// Note:
66+
// No SSL/WSS support for client in Async mode
67+
// TLS lib need a sync interface!
68+
69+
#ifndef ESP8266
70+
#error "network type ESP8266 ASYNC only possible on the ESP mcu!"
71+
#endif
72+
73+
#include <ESP8266WiFi.h>
74+
#include <ESPAsyncTCP.h>
75+
#include <ESPAsyncTCPbuffer.h>
76+
#define WEBSOCKETS_NETWORK_CLASS AsyncTCPbuffer
77+
#define WEBSOCKETS_NETWORK_SERVER_CLASS AsyncServer
78+
79+
#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
6180

6281
#ifndef ESP8266
6382
#error "network type ESP8266 only possible on the ESP mcu!"
@@ -110,6 +129,21 @@ typedef enum {
110129
///< %xB-F are reserved for further control frames
111130
} WSopcode_t;
112131

132+
typedef struct {
133+
134+
bool fin;
135+
bool rsv1;
136+
bool rsv2;
137+
bool rsv3;
138+
139+
WSopcode_t opCode;
140+
bool mask;
141+
142+
size_t payloadLen;
143+
144+
uint8_t * maskKey;
145+
} WSMessageHeader_t;
146+
113147
typedef struct {
114148
uint8_t num; ///< connection number
115149

@@ -134,10 +168,23 @@ typedef struct {
134168
String cExtensions; ///< client Sec-WebSocket-Extensions
135169
uint16_t cVersion; ///< client Sec-WebSocket-Version
136170

171+
1E79 uint8_t cWsRXsize; ///< State of the RX
172+
uint8_t cWsHeader[WEBSOCKETS_MAX_HEADER_SIZE]; ///< RX WS Message buffer
173+
WSMessageHeader_t cWsHeaderDecode;
174+
175+
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
176+
String cHttpLine; ///< HTTP header lines
177+
#endif
178+
137179
} WSclient_t;
138180

181+
182+
139183
class WebSockets {
140184
protected:
185+
186+
typedef std::function<void(WSclient_t * client, bool ok)> WSreadWaitCb;
187+
141188
virtual void clientDisconnect(WSclient_t * client);
142189
virtual bool clientIsConnected(WSclient_t * client);
143190

@@ -146,14 +193,20 @@ class WebSockets {
146193
void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0);
147194
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);
148195

196+
void headerDone(WSclient_t * client);
149197

150198
void handleWebsocket(WSclient_t * client);
151199

152-
bool readWait(WSclient_t * client, uint8_t *out, size_t n);
200+
bool handleWebsocketWaitFor(WSclient_t * client, size_t size);
201+
void handleWebsocketCb(WSclient_t * client);
202+
void handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * payload);
153203

154204
String acceptKey(String clientKey);
155205
String base64_encode(uint8_t * data, size_t length);
156206

207+
bool readCb(WSclient_t * client, uint8_t *out, size_t n, WSreadWaitCb cb);
208+
209+
157210
};
158211

159212
#endif /* WEBSOCKETS_H_ */

src/WebSocketsClient.cpp

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ WebSocketsClient::~WebSocketsClient() {
4040
void WebSocketsClient::begin(const char *host, uint16_t port, const char * url) {
4141
_host = host;
4242
_port = port;
43+
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
4344
_fingerprint = "";
45+
#endif
4446

4547
_client.num = 0;
4648
_client.status = WSC_NOT_CONNECTED;
@@ -141,10 +143,12 @@ void WebSocketsClient::loop(void) {
141143

142144
} else {
143145
DEBUG_WEBSOCKETS("[WS-Client] connection to %s:%u Faild\n", _host.c_str(), _port);
144-
delay(10); //some litle delay to not flood the server
146+
delay(10); //some little delay to not flood the server
145147
}
146148
} else {
149+
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
147150
handleClientData();
151+
#endif
148152
}
149153
}
150154

@@ -248,12 +252,15 @@ void WebSocketsClient::messageRecived(WSclient_t * client, WSopcode_t opcode, ui
248252
*/
249253
void WebSocketsClient::clientDisconnect(WSclient_t * client) {
250254

255+
bool event = false;
256+
251257
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
252258
if(client->isSSL && client->ssl) {
253259
if(client->ssl->connected()) {
254260
client->ssl->flush();
255261
client->ssl->stop();
256262
}
263+
event = true;
257264
delete client->ssl;
258265
client->ssl = NULL;
259266
client->tcp = NULL;
@@ -265,6 +272,7 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) {
265272
client->tcp->flush();
266273
client->tcp->stop();
267274
}
275+
event = true;
268276
delete client->tcp;
269277
client->tcp = NULL;
270278
}
@@ -280,9 +288,9 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) {
280288
client->status = WSC_NOT_CONNECTED;
281289

282290
DEBUG_WEBSOCKETS("[WS-Client] client disconnected.\n");
283-
284-
runCbEvent(WStype_DISCONNECTED, NULL, 0);
285-
291+
if(event) {
292+
runCbEvent(WStype_DISCONNECTED, NULL, 0);
293+
}
286294
}
287295

288296
/**
@@ -316,7 +324,7 @@ bool WebSocketsClient::clientIsConnected(WSclient_t * client) {
316324

317325
return false;
318326
}
319-
327+
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
320328
/**
321329
* Handel incomming data from Client
322330
*/
@@ -325,7 +333,10 @@ void WebSocketsClient::handleClientData(void) {
325333
if(len > 0) {
326334
switch(_client.status) {
327335
case WSC_HEADER:
328-
handleHeader(&_client);
336+
{
337+
String headerLine = _client->tcp->readStringUntil('\n');
338+
handleHeader(&_client, &headerLine);
339+
}
329340
break;
330341
case WSC_CONNECTED:
331342
WebSockets::handleWebsocket(&_client);
@@ -335,10 +346,11 @@ void WebSocketsClient::handleClientData(void) {
335346
break;
336347
}
337348
}
338-
#ifdef ESP8266
349+
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
339350
delay(0);
340351
#endif
341352
}
353+
#endif
342354

343355
/**
344356
* send the WebSocket header to Server
@@ -377,6 +389,10 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
377389

378390
client->tcp->write(handshake.c_str(), handshake.length());
379391

392+
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
393+
client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine)));
394+
#endif
395+
380396
DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header... Done (%uus).\n", (micros() - start));
381397

382398
}
@@ -385,20 +401,19 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
385401
* handle the WebSocket header reading
386402
* @param client WSclient_t * ptr to the client struct
387403
*/
388-
void WebSocketsClient::handleHeader(WSclient_t * client) {
404+
void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
389405

390-
String headerLine = client->tcp->readStringUntil('\n');
391-
headerLine.trim(); // remove \r
406+
headerLine->trim(); // remove \r
392407

393-
if(headerLine.length() > 0) {
394-
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine.c_str());
408+
if(headerLine->length() > 0) {
409+
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str());
395410

396-
if(headerLine.startsWith("HTTP/1.")) {
411+
if(headerLine->startsWith("HTTP/1.")) {
397412
// "HTTP/1.1 101 Switching Protocols"
398-
client->cCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt();
399-
} else if(headerLine.indexOf(':')) {
400-
String headerName = headerLine.substring(0, headerLine.indexOf(':'));
401-
String headerValue = headerLine.substring(headerLine.indexOf(':') + 2);
413+
client->cCode = headerLine->substring(9, headerLine->indexOf(' ', 9)).toInt();
414+
} else if(headerLine->indexOf(':')) {
415+
String headerName = headerLine->substring(0, headerLine->indexOf(':'));
416+
String headerValue = headerLine->substring(headerLine->indexOf(':') + 2);
402417

403418
if(headerName.equalsIgnoreCase("Connection")) {
404419
if(headerValue.indexOf("Upgrade") >= 0) {
@@ -419,9 +434,14 @@ void WebSocketsClient::handleHeader(WSclient_t * client) {
419434
client->cVersion = headerValue.toInt();
420435
}
421436
} else {
422-
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine.c_str());
437+
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str());
423438
}
424439

440+
(*headerLine) = "";
441+
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
442+
client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine)));
443+
#endif
444+
425445
} else {
426446
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header read fin.\n");
427447
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Client settings:\n");
@@ -456,6 +476,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client) {
456476
}
457477

458478
if(ok) {
479+
459480
if(client->cAccept.length() == 0) {
460481
ok = false;
461482
} else {
@@ -471,8 +492,8 @@ void WebSocketsClient::handleHeader(WSclient_t * client) {
471492
if(ok) {
472493

473494
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Websocket connection init done.\n");
495+
headerDone(client);
474496

475-
client->status = WSC_CONNECTED;
476497

477498
runCbEvent(WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length());
478499

src/WebSocketsClient.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,12 @@ class WebSocketsClient: private WebSockets {
7575
void clientDisconnect(WSclient_t * client);
7676
bool clientIsConnected(WSclient_t * client);
7777

78-
void handleNewClients(void);
78+
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
7979
void handleClientData(void);
80+
#endif
8081

8182
void sendHeader(WSclient_t * client);
82-
void handleHeader(WSclient_t * client);
83+
void handleHeader(WSclient_t * client, String * headerLine);
8384

8485
/**
8586
* called for sending a Event to the app

0 commit comments

Comments
 (0)
0