diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c062a23..ca27402 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,9 +22,9 @@ jobs: - core: esp32:esp32 board: esp32:esp32:esp32 index_url: https://espressif.github.io/arduino-esp32/package_esp32_index.json - - core: esp32:esp32 - board: esp32:esp32:esp32 - index_url: https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json + # - core: esp32:esp32 + # board: esp32:esp32:esp32 + # index_url: https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json - core: esp8266:esp8266 board: esp8266:esp8266:huzzah index_url: https://arduino.esp8266.com/stable/package_esp8266com_index.json @@ -55,7 +55,7 @@ jobs: - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.12 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.14 - name: Install ESPAsyncTCP (ESP8266) if: ${{ matrix.core == 'esp8266:esp8266' }} @@ -127,8 +127,8 @@ jobs: - env: ci-esp8266 board: d1_mini - - env: ci-raspberrypi - board: rpipicow + # - env: ci-raspberrypi + # board: rpipicow steps: - name: Checkout uses: actions/checkout@v4 diff --git a/README.md b/README.md index a40260b..b4a3442 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,20 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - (perf) Lot of code cleanup and optimizations - (perf) Performance improvements in terms of memory, speed and size +--- + +## WARNING: Important notes about future version 4.x + +This ESPAsyncWebServer fork is now at version 3.x. + +Next version 4.x will: + +1. Drop support for ESP8266, which goes EOL in a few years. All ESP8266 boards can be replaced by equivalent ESP32 boards. +2. Drop support for Arduino 2.x and ESP-IDF 4.x. The library will be compatible with Arduino 3.x and ESP-IDF 5.x. +3. Drop support for ArduinoJson 5.x and 6.x. The library will be compatible with ArduinoJson 7.x. + +So if you need one of these feature, you will have to stick with 3.x or another fork. + ## Dependencies **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations, but its name had to stay `ESP Async WebServer` in Arduino Registry. @@ -61,13 +75,13 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.22 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.23 ``` **Dependencies:** -- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.12` - Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.12](https://github.com/mathieucarbou/AsyncTCP/releases) +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.14` + Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.14](https://github.com/mathieucarbou/AsyncTCP/releases) - **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip` @@ -85,9 +99,9 @@ AsyncTCPSock can be used instead of AsyncTCP by excluding AsyncTCP from the libr lib_compat_mode = strict lib_ldf_mode = chain lib_deps = - ; mathieucarbou/AsyncTCP @ 3.2.12 + ; mathieucarbou/AsyncTCP @ 3.2.14 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.22 + mathieucarbou/ESPAsyncWebServer @ 3.3.23 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,14 +109,14 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.22`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.23`: ```bash > brew install autocannon > autocannon -c 10 -w 10 -d 20 http://192.168.4.1 ``` -With `mathieucarbou/AsyncTCP @ 3.2.12` +With `mathieucarbou/AsyncTCP @ 3.2.14` [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) @@ -110,6 +124,40 @@ With `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png) +**SSE performance** + +In the example, there is an endpoint `/events` with some comments showing how these metrics are calculated. + +Test is running for 20 seconds with 10 connections. + +``` +// With AsyncTCP, with 10 workers: no message discarded from the queue +// +// Total: 1875 events, 468.75000000000000000000 events / second +// Total: 1870 events, 467.50000000000000000000 events / second +// Total: 1871 events, 467.75000000000000000000 events / second +// Total: 1875 events, 468.75000000000000000000 events / second +// Total: 1871 events, 467.75000000000000000000 events / second +// Total: 1805 events, 451.25000000000000000000 events / second +// Total: 1803 events, 450.75000000000000000000 events / second +// Total: 1873 events, 468.25000000000000000000 events / second +// Total: 1872 events, 468.00000000000000000000 events / second +// Total: 1805 events, 451.25000000000000000000 events / second +// +// With AsyncTCPSock, with 10 workers: no message discarded from the queue +// +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1181 events, 295.25000000000000000000 events / second +// Total: 1182 events, 295.50000000000000000000 events / second +// Total: 1240 events, 310.00000000000000000000 events / second +// Total: 1181 events, 295.25000000000000000000 events / second +// Total: 1181 events, 295.25000000000000000000 events / second +// Total: 1183 events, 295.75000000000000000000 events / second +``` + ## Important recommendations Most of the crashes are caused by improper configuration of the library for the project. @@ -574,7 +622,7 @@ Endpoints which consume JSON can use a special handler to get ready to use JSON #include "ArduinoJson.h" AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/rest/endpoint", [](AsyncWebServerRequest *request, JsonVariant &json) { - JsonObject& jsonObj = json.as(); + JsonObject jsonObj = json.as(); // ... }); server.addHandler(handler); diff --git a/docs/index.md b/docs/index.md index 4af119c..d47c640 100644 --- a/docs/index.md +++ b/docs/index.md @@ -52,6 +52,20 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - (perf) Lot of code cleanup and optimizations - (perf) Performance improvements in terms of memory, speed and size +--- + +## WARNING: Important notes about future version 4.x + +This ESPAsyncWebServer fork is now at version 3.x. + +Next version 4.x will: + +1. Drop support for ESP8266, which goes EOL in a few years. All ESP8266 boards can be replaced by equivalent ESP32 boards. +2. Drop support for Arduino 2.x and ESP-IDF 4.x. The library will be compatible with Arduino 3.x and ESP-IDF 5.x. +3. Drop support for ArduinoJson 5.x and 6.x. The library will be compatible with ArduinoJson 7.x. + +So if you need one of these feature, you will have to stick with 3.x or another fork. + ## Dependencies **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations, but its name had to stay `ESP Async WebServer` in Arduino Registry. @@ -61,13 +75,13 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.22 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.23 ``` **Dependencies:** -- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.12` - Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.12](https://github.com/mathieucarbou/AsyncTCP/releases) +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.14` + Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.14](https://github.com/mathieucarbou/AsyncTCP/releases) - **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip` @@ -85,9 +99,9 @@ AsyncTCPSock can be used instead of AsyncTCP by excluding AsyncTCP from the libr lib_compat_mode = strict lib_ldf_mode = chain lib_deps = - ; mathieucarbou/AsyncTCP @ 3.2.12 + ; mathieucarbou/AsyncTCP @ 3.2.14 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.22 + mathieucarbou/ESPAsyncWebServer @ 3.3.23 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,14 +109,14 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.22`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.23`: ```bash > brew install autocannon > autocannon -c 10 -w 10 -d 20 http://192.168.4.1 ``` -With `mathieucarbou/AsyncTCP @ 3.2.12` +With `mathieucarbou/AsyncTCP @ 3.2.14` [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) @@ -110,6 +124,40 @@ With `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png) +**SSE performance** + +In the example, there is an endpoint `/events` with some comments showing how these metrics are calculated. + +Test is running for 20 seconds with 10 connections. + +``` +// With AsyncTCP, with 10 workers: no message discarded from the queue +// +// Total: 1875 events, 468.75000000000000000000 events / second +// Total: 1870 events, 467.50000000000000000000 events / second +// Total: 1871 events, 467.75000000000000000000 events / second +// Total: 1875 events, 468.75000000000000000000 events / second +// Total: 1871 events, 467.75000000000000000000 events / second +// Total: 1805 events, 451.25000000000000000000 events / second +// Total: 1803 events, 450.75000000000000000000 events / second +// Total: 1873 events, 468.25000000000000000000 events / second +// Total: 1872 events, 468.00000000000000000000 events / second +// Total: 1805 events, 451.25000000000000000000 events / second +// +// With AsyncTCPSock, with 10 workers: no message discarded from the queue +// +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1181 events, 295.25000000000000000000 events / second +// Total: 1182 events, 295.50000000000000000000 events / second +// Total: 1240 events, 310.00000000000000000000 events / second +// Total: 1181 events, 295.25000000000000000000 events / second +// Total: 1181 events, 295.25000000000000000000 events / second +// Total: 1183 events, 295.75000000000000000000 events / second +``` + ## Important recommendations Most of the crashes are caused by improper configuration of the library for the project. @@ -1232,7 +1280,7 @@ For actual serving the file. ### Param Rewrite With Matching -It is possible to rewrite the request url with parameter matchg. Here is an example with one parameter: +It is possible to rewrite the request url with parameter match. Here is an example with one parameter: Rewrite for example "/radio/{frequence}" -> "/radio?f={frequence}" ```cpp diff --git a/examples/CaptivePortal/CaptivePortal.ino b/examples/CaptivePortal/CaptivePortal.ino index d44e7e6..69232d8 100644 --- a/examples/CaptivePortal/CaptivePortal.ino +++ b/examples/CaptivePortal/CaptivePortal.ino @@ -16,7 +16,7 @@ AsyncWebServer server(80); class CaptiveRequestHandler : public AsyncWebHandler { public: - bool canHandle(__unused AsyncWebServerRequest* request) { + bool canHandle(__unused AsyncWebServerRequest* request) const override { return true; } diff --git a/examples/Filters/Filters.ino b/examples/Filters/Filters.ino index 6479c15..2335364 100644 --- a/examples/Filters/Filters.ino +++ b/examples/Filters/Filters.ino @@ -18,11 +18,11 @@ AsyncWebServer server(80); class CaptiveRequestHandler : public AsyncWebHandler { public: - bool canHandle(__unused AsyncWebServerRequest* request) { + bool canHandle(__unused AsyncWebServerRequest* request) const override { return true; } - void handleRequest(AsyncWebServerRequest* request) { + void handleRequest(AsyncWebServerRequest* request) override { AsyncResponseStream* response = request->beginResponseStream("text/html"); response->print("Captive Portal"); response->print("

This is out captive portal front page.

"); diff --git a/examples/Issue162/Issue162.ino b/examples/Issue162/Issue162.ino new file mode 100644 index 0000000..9f7312f --- /dev/null +++ b/examples/Issue162/Issue162.ino @@ -0,0 +1,84 @@ +/** + * + * Connect to AP and run in bash: + * + * > while true; do echo "PING"; sleep 0.1; done | websocat ws://192.168.4.1/ws + * + */ +#include +#ifdef ESP8266 + #include +#endif +#ifdef ESP32 + #include +#endif +#include + +#include +AsyncWebServer server(80); +AsyncWebSocket ws("/ws"); + +void onWsEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len) { + if (type == WS_EVT_CONNECT) { + Serial.printf("Client #%" PRIu32 " connected.\n", client->id()); + } else if (type == WS_EVT_DISCONNECT) { + Serial.printf("Client #%" PRIu32 " disconnected.\n", client->id()); + } else if (type == WS_EVT_ERROR) { + Serial.printf("Client #%" PRIu32 " error.\n", client->id()); + } else if (type == WS_EVT_DATA) { + Serial.printf("Client #%" PRIu32 " len: %u\n", client->id(), len); + } else if (type == WS_EVT_PONG) { + Serial.printf("Client #%" PRIu32 " pong.\n", client->id()); + } else if (type == WS_EVT_PING) { + Serial.printf("Client #%" PRIu32 " ping.\n", client->id()); + } +} + +void setup() { + Serial.begin(115200); + + WiFi.mode(WIFI_AP); + WiFi.softAP("esp-captive"); + + ws.onEvent(onWsEvent); + server.addHandler(&ws); + + server.on("/close_all_ws_clients", HTTP_GET | HTTP_POST, [](AsyncWebServerRequest* request) { + Serial.println("Closing all WebSocket clients..."); + ws.closeAll(); + request->send(200, "application/json", "{\"status\":\"all clients closed\"}"); + }); + + server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/html", R"rawliteral( + + + + + +

+ + + )rawliteral"); + }); + + server.begin(); +} + +void loop() { + vTaskDelete(NULL); +} diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 1084528..8d34765 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -87,6 +87,8 @@ const char* htmlContent PROGMEM = R"( )"; +const size_t htmlContentLength = strlen_P(htmlContent); + const char* staticContent PROGMEM = R"( @@ -467,6 +469,40 @@ void setup() { request->send(response); }); + // curl -N -v -X GET http://192.168.4.1/chunked.html --output - + // curl -N -v -X GET -H "if-none-match: 4272" http://192.168.4.1/chunked.html --output - + server.on("/chunked.html", HTTP_GET, [](AsyncWebServerRequest* request) { + String len = String(htmlContentLength); + + if (request->header(asyncsrv::T_INM) == len) { + request->send(304); + return; + } + + AsyncWebServerResponse* response = request->beginChunkedResponse("text/html", [](uint8_t* buffer, size_t maxLen, size_t index) -> size_t { + Serial.printf("%u / %u\n", index, htmlContentLength); + + // finished ? + if (htmlContentLength <= index) { + Serial.println("finished"); + return 0; + } + + // serve a maximum of 1024 or maxLen bytes of the remaining content + const int chunkSize = min((size_t)1024, min(maxLen, htmlContentLength - index)); + Serial.printf("sending: %u\n", chunkSize); + + memcpy(buffer, htmlContent + index, chunkSize); + + return chunkSize; + }); + + response->addHeader(asyncsrv::T_Cache_Control, "public,max-age=60"); + response->addHeader(asyncsrv::T_ETag, len); + + request->send(response); + }); + /* ❯ curl -I -X HEAD http://192.168.4.1/download HTTP/1.1 200 OK @@ -516,18 +552,6 @@ void setup() { #if __has_include("ArduinoJson.h") // JSON - // receives JSON and sends JSON - jsonHandler->onRequest([](AsyncWebServerRequest* request, JsonVariant& json) { - // JsonObject jsonObj = json.as(); - // ... - - AsyncJsonResponse* response = new AsyncJsonResponse(); - JsonObject root = response->getRoot().to(); - root["hello"] = "world"; - response->setLength(); - request->send(response); - }); - // sends JSON // curl -v -X GET http://192.168.4.1/json1 server.on("/json1", HTTP_GET, [](AsyncWebServerRequest* request) { @@ -543,11 +567,23 @@ void setup() { AsyncResponseStream* response = request->beginResponseStream("application/json"); JsonDocument doc; JsonObject root = doc.to(); - root["hello"] = "world"; + root["foo"] = "bar"; serializeJson(root, *response); request->send(response); }); + // curl -v -X POST -H 'Content-Type: application/json' -d '{"name":"You"}' http://192.168.4.1/json2 + // curl -v -X PUT -H 'Content-Type: application/json' -d '{"name":"You"}' http://192.168.4.1/json2 + jsonHandler->setMethod(HTTP_POST | HTTP_PUT); + jsonHandler->onRequest([](AsyncWebServerRequest* request, JsonVariant& json) { + serializeJson(json, Serial); + AsyncJsonResponse* response = new AsyncJsonResponse(); + JsonObject root = response->getRoot().to(); + root["hello"] = json.as()["name"]; + response->setLength(); + request->send(response); + }); + // MessagePack // receives MessagePack and sends MessagePack @@ -607,11 +643,82 @@ void setup() { } }); + // SSS endpoints + // sends a message every 10 ms + // // go to http://192.168.4.1/sse + // > curl -v -N -H "Accept: text/event-stream" http://192.168.4.1/events + // + // some perf tests: + // launch 16 concurrent workers for 30 seconds + // > for i in {1..16}; do ( count=$(gtimeout 30 curl -s -N -H "Accept: text/event-stream" http://192.168.4.1/events 2>&1 | grep -c "^data:"); echo "Total: $count events, $(echo "$count / 4" | bc -l) events / second" ) & done; + // + // With AsyncTCP, with 16 workers: a lot of Too many messages queued: deleting message + // + // Total: 119 events, 29.75000000000000000000 events / second + // Total: 727 events, 181.75000000000000000000 events / second + // Total: 1386 events, 346.50000000000000000000 events / second + // Total: 1385 events, 346.25000000000000000000 events / second + // Total: 1276 events, 319.00000000000000000000 events / second + // Total: 1411 events, 352.75000000000000000000 events / second + // Total: 1276 events, 319.00000000000000000000 events / second + // Total: 1333 events, 333.25000000000000000000 events / second + // Total: 1250 events, 312.50000000000000000000 events / second + // Total: 1275 events, 318.75000000000000000000 events / second + // Total: 1271 events, 317.75000000000000000000 events / second + // Total: 1271 events, 317.75000000000000000000 events / second + // Total: 1254 events, 313.50000000000000000000 events / second + // Total: 1251 events, 312.75000000000000000000 events / second + // Total: 1254 events, 313.50000000000000000000 events / second + // Total: 1262 events, 315.50000000000000000000 events / second + // + // With AsyncTCP, with 10 workers: + // + // Total: 1875 events, 468.75000000000000000000 events / second + // Total: 1870 events, 467.50000000000000000000 events / second + // Total: 1871 events, 467.75000000000000000000 events / second + // Total: 1875 events, 468.75000000000000000000 events / second + // Total: 1871 events, 467.75000000000000000000 events / second + // Total: 1805 events, 451.25000000000000000000 events / second + // Total: 1803 events, 450.75000000000000000000 events / second + // Total: 1873 events, 468.25000000000000000000 events / second + // Total: 1872 events, 468.00000000000000000000 events / second + // Total: 1805 events, 451.25000000000000000000 events / second + // + // With AsyncTCPSock, with 16 workers: ESP32 CRASH !!! + // + // With AsyncTCPSock, with 10 workers: + // + // Total: 1242 events, 310.50000000000000000000 events / second + // Total: 1242 events, 310.50000000000000000000 events / second + // Total: 1242 events, 310.50000000000000000000 events / second + // Total: 1242 events, 310.50000000000000000000 events / second + // Total: 1181 events, 295.25000000000000000000 events / second + // Total: 1182 events, 295.50000000000000000000 events / second + // Total: 1240 events, 310.00000000000000000000 events / second + // Total: 1181 events, 295.25000000000000000000 events / second + // Total: 1181 events, 295.25000000000000000000 events / second + // Total: 1183 events, 295.75000000000000000000 events / second + // server.addHandler(&events); - // Run: websocat ws://192.168.4.1/ws - server.addHandler(&ws); + // Run in terminal 1: websocat ws://192.168.4.1/ws => stream data + // Run in terminal 2: websocat ws://192.168.4.1/ws => stream data + // Run in terminal 3: websocat ws://192.168.4.1/ws => should fail: + /* +❯ websocat ws://192.168.4.1/ws +websocat: WebSocketError: WebSocketError: Received unexpected status code (503 Service Unavailable) +websocat: error running + */ + server.addHandler(&ws).addMiddleware([](AsyncWebServerRequest* request, ArMiddlewareNext next) { + if (ws.count() > 2) { + // too many clients - answer back immediately and stop processing next middlewares and handler + request->send(503, "text/plain", "Server is busy"); + } else { + // process next middleware and at the end the handler + next(); + } + }); #if __has_include("ArduinoJson.h") server.addHandler(jsonHandler); @@ -624,7 +731,7 @@ void setup() { } uint32_t lastSSE = 0; -uint32_t deltaSSE = 5; +uint32_t deltaSSE = 10; uint32_t lastWS = 0; uint32_t deltaWS = 100; @@ -637,9 +744,9 @@ void loop() { } if (now - lastWS >= deltaWS) { ws.printfAll("kp%.4f", (10.0 / 3.0)); - for (auto& client : ws.getClients()) { - client.printf("kp%.4f", (10.0 / 3.0)); - } + // for (auto& client : ws.getClients()) { + // client.printf("kp%.4f", (10.0 / 3.0)); + // } lastWS = millis(); } } diff --git a/library.json b/library.json index 5093582..f7e219c 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.22", + "version": "3.3.23", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "AsyncTCP", - "version": "^3.2.12", + "version": "^3.2.14", "platforms": "espressif32" }, { diff --git a/library.properties b/library.properties index 41908ca..865e911 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=ESP Async WebServer includes=ESPAsyncWebServer.h -version=3.3.22 +version=3.3.23 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/platformio.ini b/platformio.ini index 0b87942..485f48b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -6,6 +6,7 @@ src_dir = examples/SimpleServer ; src_dir = examples/StreamFiles ; src_dir = examples/Filters ; src_dir = examples/Issue85 +; src_dir = examples/Issue162 [env] framework = arduino @@ -29,8 +30,8 @@ lib_ldf_mode = chain lib_deps = ; bblanchon/ArduinoJson @ 5.13.4 ; bblanchon/ArduinoJson @ 6.21.5 - bblanchon/ArduinoJson @ 7.2.0 - mathieucarbou/AsyncTCP @ 3.2.12 + bblanchon/ArduinoJson @ 7.2.1 + mathieucarbou/AsyncTCP @ 3.2.14 board = esp32dev board_build.partitions = partitions-4MB.csv board_build.filesystem = littlefs @@ -48,21 +49,21 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 lib_deps = - mathieucarbou/AsyncTCP @ 3.2.12 + mathieucarbou/AsyncTCP @ 3.2.14 [env:arduino-310] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc3/platform-espressif32.zip ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 ; board = esp32-h2-devkitm-1 [env:perf-test-AsyncTCP] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc3/platform-espressif32.zip build_flags = ${env.build_flags} -D PERF_TEST=1 [env:perf-test-AsyncTCPSock] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc3/platform-espressif32.zip lib_deps = https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip build_flags = ${env.build_flags} @@ -73,14 +74,14 @@ platform = espressif8266 ; board = huzzah board = d1_mini lib_deps = - bblanchon/ArduinoJson @ 7.2.0 + bblanchon/ArduinoJson @ 7.2.1 esphome/ESPAsyncTCP-esphome @ 2.0.0 [env:raspberrypi] platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = rpipicow lib_deps = - bblanchon/ArduinoJson @ 7.2.0 + bblanchon/ArduinoJson @ 7.2.1 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 lib_ignore = lwIP_ESPHost @@ -101,24 +102,24 @@ board = ${sysenv.PIO_BOARD} platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip board = ${sysenv.PIO_BOARD} lib_deps = - mathieucarbou/AsyncTCP @ 3.2.12 + mathieucarbou/AsyncTCP @ 3.2.14 [env:ci-arduino-310] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc3/platform-espressif32.zip board = ${sysenv.PIO_BOARD} [env:ci-esp8266] platform = espressif8266 board = ${sysenv.PIO_BOARD} lib_deps = - bblanchon/ArduinoJson @ 7.2.0 + bblanchon/ArduinoJson @ 7.2.1 esphome/ESPAsyncTCP-esphome @ 2.0.0 [env:ci-raspberrypi] platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = ${sysenv.PIO_BOARD} lib_deps = - bblanchon/ArduinoJson @ 7.2.0 + bblanchon/ArduinoJson @ 7.2.1 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 lib_ignore = lwIP_ESPHost diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 9efb6db..b89c0d5 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -544,7 +544,7 @@ void AsyncWebSocketClient::_onData(void* pbuf, size_t plen) { } } if (datalen > 0) - _server->_handleEvent(this, WS_EVT_DATA, (void*)&_pinfo, (uint8_t*)data, datalen); + _server->_handleEvent(this, WS_EVT_DATA, (void*)&_pinfo, data, datalen); _pinfo.index += datalen; } else if ((datalen + _pinfo.index) == _pinfo.len) { @@ -568,11 +568,12 @@ void AsyncWebSocketClient::_onData(void* pbuf, size_t plen) { _queueControl(WS_DISCONNECT, data, datalen); } } else if (_pinfo.opcode == WS_PING) { + _server->_handleEvent(this, WS_EVT_PING, NULL, NULL, 0); _queueControl(WS_PONG, data, datalen); } else if (_pinfo.opcode == WS_PONG) { if (datalen != AWSC_PING_PAYLOAD_LEN || memcmp(AWSC_PING_PAYLOAD, data, AWSC_PING_PAYLOAD_LEN) != 0) - _server->_handleEvent(this, WS_EVT_PONG, NULL, data, datalen); - } else if (_pinfo.opcode < 8) { // continuation or text/binary frame + _server->_handleEvent(this, WS_EVT_PONG, NULL, NULL, 0); + } else if (_pinfo.opcode < WS_DISCONNECT) { // continuation or text/binary frame _server->_handleEvent(this, WS_EVT_DATA, (void*)&_pinfo, data, datalen); if (_pinfo.final) _pinfo.num = 0; @@ -586,7 +587,7 @@ void AsyncWebSocketClient::_onData(void* pbuf, size_t plen) { } // restore byte as _handleEvent may have added a null terminator i.e., data[len] = 0; - if (datalen > 0) + if (datalen) data[datalen] = datalast; data += datalen; diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 8ad06ea..671c866 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -104,6 +104,7 @@ typedef enum { WS_MSG_SENDING, WS_MSG_ERROR } AwsMessageStatus; typedef enum { WS_EVT_CONNECT, WS_EVT_DISCONNECT, + WS_EVT_PING, WS_EVT_PONG, WS_EVT_ERROR, WS_EVT_DATA } AwsEventType; diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index c77102e..e58a155 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.22" +#define ASYNCWEBSERVER_VERSION "3.3.23" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 22 +#define ASYNCWEBSERVER_VERSION_REVISION 23 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX