// SPDX-License-Identifier: LGPL-3.0-or-later // Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov // // WebSocket example using the easy to use AsyncWebSocketMessageHandler handler that only supports unfragmented messages // #include #ifdef ESP32 #include #include #elif defined(ESP8266) #include #include #elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) #include #include #endif #include static AsyncWebServer server(80); // create an easy-to-use handler static AsyncWebSocketMessageHandler wsHandler; // add it to the websocket server static AsyncWebSocket ws("/ws", wsHandler.eventHandler()); // alternatively you can do as usual: // // static AsyncWebSocket ws("/ws"); // ws.onEvent(wsHandler.eventHandler()); static const char *htmlContent PROGMEM = R"( WebSocket

WebSocket Example

<>Open your browser console!

)"; static const size_t htmlContentLength = strlen_P(htmlContent); void setup() { Serial.begin(115200); #ifndef CONFIG_IDF_TARGET_ESP32H2 WiFi.mode(WIFI_AP); WiFi.softAP("esp-captive"); #endif // serves root html page server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { request->send(200, "text/html", (const uint8_t *)htmlContent, htmlContentLength); }); wsHandler.onConnect([](AsyncWebSocket *server, AsyncWebSocketClient *client) { Serial.printf("Client %" PRIu32 " connected\n", client->id()); server->textAll("New client: " + String(client->id())); }); wsHandler.onDisconnect([](AsyncWebSocket *server, uint32_t clientId) { Serial.printf("Client %" PRIu32 " disconnected\n", clientId); server->textAll("Client " + String(clientId) + " disconnected"); }); wsHandler.onError([](AsyncWebSocket *server, AsyncWebSocketClient *client, uint16_t errorCode, const char *reason, size_t len) { Serial.printf("Client %" PRIu32 " error: %" PRIu16 ": %s\n", client->id(), errorCode, reason); }); wsHandler.onMessage([](AsyncWebSocket *server, AsyncWebSocketClient *client, const uint8_t *data, size_t len) { Serial.printf("Client %" PRIu32 " data: %s\n", client->id(), (const char *)data); }); wsHandler.onFragment([](AsyncWebSocket *server, AsyncWebSocketClient *client, const AwsFrameInfo *frameInfo, const uint8_t *data, size_t len) { Serial.printf("Client %" PRIu32 " fragment %" PRIu32 ": %s\n", client->id(), frameInfo->num, (const char *)data); }); server.addHandler(&ws); server.begin(); } static uint32_t lastWS = 0; static uint32_t deltaWS = 2000; void loop() { uint32_t now = millis(); if (now - lastWS >= deltaWS) { ws.cleanupClients(); ws.printfAll("now: %" PRIu32 "\n", now); lastWS = millis(); #ifdef ESP32 Serial.printf("Free heap: %" PRIu32 "\n", ESP.getFreeHeap()); #endif } }