ESP32 WebServer Bibliotheksreferenz

Überblick

Die DIYables_ESP32_WebServer-Bibliothek bietet eine umfassende Lösung zum Erstellen von mehrseitigen Webservern mit WebSocket-Unterstützung auf ESP32-Boards.

Erforderliche Hardware

1×ESP32 ESP-WROOM-32 Entwicklungsmodul
1×USB-Kabel Typ-A zu Typ-C (für USB-A PC)
1×USB-Kabel Typ-C zu Typ-C (für USB-C PC)
1×(Empfohlen) Schraubklemmen-Erweiterungsboard für ESP32
1×(Empfohlen) Breakout Expansion Board for ESP32
1×(Empfohlen) Stromverteiler für ESP32

Oder Sie können die folgenden Kits kaufen:

1×DIYables ESP32 Starter-Kit (ESP32 enthalten)
1×DIYables Sensor-Kit (30 Sensoren/Displays)
1×DIYables Sensor-Kit (18 Sensoren/Displays)
Offenlegung: Einige der in diesem Abschnitt bereitgestellten Links sind Amazon-Affiliate-Links. Wir können eine Provision für Käufe erhalten, die über diese Links getätigt werden, ohne zusätzliche Kosten für Sie. Wir schätzen Ihre Unterstützung.

Installation

Schnelle Schritte

Folgen Sie diesen Anweisungen Schritt für Schritt:

  • Wenn dies das erste Mal ist, dass Sie den ESP32 verwenden, lesen Sie das Tutorial zur Einrichtung der Entwicklungsumgebung für ESP32 in der Arduino IDE.
  • Schließen Sie das ESP32-Board mit einem USB-Kabel an Ihren Computer an.
  • Öffnen Sie die Arduino IDE auf Ihrem Computer.
  • Wählen Sie das passende ESP32-Board (z. B. ESP32) und den COM-Port aus.
  • Öffnen Sie den Bibliotheks-Manager, indem Sie auf das Library Manager-Symbol auf der linken Seite der Arduino IDE klicken.
  • Suchen Sie nach Web Server for ESP32 und finden Sie die mWebSockets von DIYables.
  • Klicken Sie auf die Installieren-Schaltfläche, um die mWebSockets-Bibliothek hinzuzufügen.
ESP32-Webserver-Bibliothek

WebSocket-Unterstützung (integriert)

Die WebSocket-Funktionalität ist jetzt direkt in dieser Bibliothek integriert!

Die WebSocket-Implementierung basiert auf der ausgezeichneten mWebSockets-Bibliothek von Dawid Kurek, die speziell für den ESP32 integriert und optimiert wurde, um die Nutzung zu erleichtern:

  • Keine zusätzliche Bibliotheksinstallation erforderlich - WebSocket-Unterstützung ist integriert
  • Für ESP32 optimiert - Vereinfachte plattformabhängige Implementierung
  • WiFi-Kompatibilität - Verwendet den nativen WiFi-Stack des ESP32
  • RFC 6455-konform - Vollständige Unterstützung des WebSocket-Protokolls
  • Echtzeit-Kommunikation - Bidirektionaler Datenaustausch

Verwendung:

  • Für alles (Webserver + WebSocket): Verwenden Sie #include <DIYables_ESP32_WebServer.h>
  • Das war's! - Die WebSocket-Funktionalität ist bei Bedarf automatisch verfügbar
  • Speichereffizient - Nicht verwendeter WebSocket-Code wird vom Compiler automatisch optimiert

Danksagungen: WebSocket-Implementierung, adaptiert aus der Bibliothek mWebSockets (LGPL-2.1-Lizenz) von Dawid Kurek, modifiziert und für eine nahtlose ESP32-Kompatibilität integriert.

Bibliotheksklassen

DIYables_ESP32_WebServer Klasse

Die Hauptklasse zur Erstellung und Verwaltung von Webservern.

Konstruktor

DIYables_ESP32_WebServer(int port = 80)

Erstellt eine Webserver-Instanz auf dem angegebenen Port (Standard: 80).

Methoden

beginnen()
void begin() void begin(const char* ssid, const char* password)

Startet den Webserver und beginnt, auf eingehende Verbindungen zu lauschen.

Überladene Versionen:

  • begin(): Starte nur den Server (WLAN muss separat von Ihrer Anwendung verbunden werden)
  • begin(ssid, password): Mit WLAN verbinden und den Server in einem einzigen Aufruf starten (veralteter Ansatz)
setNotFoundHandler()
void setNotFoundHandler(RouteHandler handler)

Legt einen benutzerdefinierten Handler für 404 Not Found-Antworten fest.

printWifiStatus()
void printWifiStatus()

Gibt den WLAN-Verbindungsstatus und die IP-Adresse im Serial Monitor aus.

handleClient()
void handleClient()

Verarbeitet eingehende Client-Anfragen. Dies sollte in der Hauptschleife wiederholt aufgerufen werden.

on()
void on(const String &uri, HTTPMethod method, THandlerFunction fn) void on(const String &uri, THandlerFunction fn) // defaults to GET

Registriert eine Handler-Funktion für eine bestimmte URI und HTTP-Methode.

Parameter:

  • uri: Der URI-Pfad (z. B., "/", "/led", "/api/data")
  • method: HTTP-Methode (GET, POST, PUT, DELETE, usw.)
  • fn: Handler-Funktion, die ausgeführt wird, wenn die Route aufgerufen wird

Hinweis: Diese Bibliothek verwendet die Methode addRoute() anstelle von on(). Siehe unten für die korrekte Verwendung.

addRoute()
void addRoute(const String &uri, RouteHandler handler)

Registriert eine Handler-Funktion für eine bestimmte URI. Dies ist die tatsächlich in der Bibliothek verwendete Methode.

RouteHandler Funktionsformat:

Routen-Handler müssen dieser genauen Signatur entsprechen:

void handlerFunction(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData)

Parameter:

  • client: WiFiClient-Referenz zum Senden von Antworten
  • method: HTTP-Methode als Zeichenkette ("GET", "POST", usw.)
  • request: Vollständige Anforderungs-URI
  • params: Abfrageparameter (QueryParams-Objekt)
  • jsonData: JSON-Payload für POST-Anfragen (bei GET leer)

Beispiele zur Handler-Implementierung:

  1. Grundlegender GET-Handler:
void handleHome(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { if (method == "GET") { String response = "<html><body><h1>Hello World</h1></body></html>"; server.sendResponse(client, response.c_str()); } } void setup() { server.addRoute("/", handleHome); }
  1. JSON-API-Handler (GET und POST):
void handleApiData(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { if (method == "POST") { if (jsonData.length() == 0) { client.println("HTTP/1.1 400 Bad Request"); client.println("Content-Type: application/json"); client.println("Connection: close"); client.println(); client.print("{\"status\":\"error\",\"message\":\"No JSON data received\"}"); return; } // Process JSON data StaticJsonDocument<200> doc; DeserializationError error = deserializeJson(doc, jsonData); if (error) { client.println("HTTP/1.1 400 Bad Request"); client.println("Content-Type: application/json"); client.println("Connection: close"); client.println(); client.print("{\"status\":\"error\",\"message\":\"Invalid JSON\"}"); return; } const char* key = doc["key"] | "none"; String response = "{\"status\":\"success\",\"received_key\":\"" + String(key) + "\"}"; server.sendResponse(client, response.c_str(), "application/json"); } else if (method == "GET") { String response = "{\"status\":\"success\",\"message\":\"GET request received\"}"; server.sendResponse(client, response.c_str(), "application/json"); } else { client.println("HTTP/1.1 405 Method Not Allowed"); client.println("Content-Type: application/json"); client.println("Connection: close"); client.println(); client.print("{\"status\":\"error\",\"message\":\"Method not allowed\"}"); } } void setup() { server.addRoute("/api/data", handleApiData); }
  1. Abfrageparameter-Handler:
void handleLedControl(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { if (method == "GET") { // Access query parameters String action = params.getValue("action"); // ?action=on if (action == "on") { digitalWrite(LED_PIN, HIGH); server.sendResponse(client, "LED turned ON"); } else if (action == "off") { digitalWrite(LED_PIN, LOW); server.sendResponse(client, "LED turned OFF"); } else { client.println("HTTP/1.1 400 Bad Request"); client.println("Content-Type: text/plain"); client.println("Connection: close"); client.println(); client.print("Invalid action. Use ?action=on or ?action=off"); } } } void setup() { server.addRoute("/led", handleLedControl); }
Antwort senden()
void sendResponse(WiFiClient& client, const char* content, const char* contentType = "text/html")

Sendet eine HTTP-Antwort an den Client.

Parameter:

  • client: WiFiClient-Verweis (in der Handler-Funktion bereitgestellt)
  • content: Inhalt des Antwortkörpers
  • contentType: MIME-Typ der Antwort (Standardwert: "text/html")

Anwendungsbeispiele:

// Send HTML response server.sendResponse(client, "<h1>Hello World</h1>"); // Send JSON response server.sendResponse(client, "{\"status\":\"ok\"}", "application/json"); // Send plain text server.sendResponse(client, "Success", "text/plain");
Authentifizierungsmethoden
aktivierenAuthentifizierung()
void enableAuthentication(const char* username, const char* password, const char* realm = "ESP32 Server")

Aktiviert die HTTP-Basisauthentifizierung für alle Routen. Sobald sie aktiviert ist, erfordern alle Routen eine Authentifizierung.

Parameter:

  • username: Benutzername für die Authentisierung (max. 31 Zeichen)
  • password: Passwort für die Authentisierung (max. 31 Zeichen)
  • realm: Authentifizierungsbereich im Browser angezeigt (max. 63 Zeichen, optional)

Anwendungsbeispiel:

// Enable authentication with default realm server.enableAuthentication("admin", "password123"); // Enable authentication with custom realm server.enableAuthentication("admin", "secure456", "My ESP32 Device");
Authentifizierung deaktivieren()
void disableAuthentication()

Deaktiviert die Authentifizierung, wodurch alle Routen wieder öffentlich zugänglich sind.

Anwendungsbeispiel:

server.disableAuthentication();
istAuthentifizierungAktiv()
bool isAuthenticationEnabled()

Gibt true zurück, wenn die Authentifizierung derzeit aktiviert ist, andernfalls false.

Anwendungsbeispiel:

if (server.isAuthenticationEnabled()) { Serial.println("Authentication is active"); } else { Serial.println("All routes are public"); }
send401()
void send401(WiFiClient& client)

Sendet eine 401 Unauthorized-Antwort mit dem passenden WWW-Authenticate-Header. Dies wird automatisch aufgerufen, wenn die Authentifizierung fehlschlägt, kann aber auch manuell in benutzerdefinierten Handlern verwendet werden.

Verwendungsbeispiel:

// Manual 401 response in a custom handler server.send401(client);
Manuelle Antwortübermittlung

Für mehr Kontrolle über HTTP-Header und Statuscodes:

void sendCustomResponse(WiFiClient& client) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: application/json"); client.println("Access-Control-Allow-Origin: *"); client.println("Connection: close"); client.println(); client.print("{\"custom\":\"response\"}"); }

Zugriff auf Abfrageparameter

Abfrageparameter-Struktur

Das QueryParams-Objekt enthält die aus der URL geparsten Abfrageparameter:

struct QueryParams { int count; // Number of parameters struct { const char* key; // Parameter name const char* value; // Parameter value } params[MAX_PARAMS]; }

Zugriff auf Abfrageparameter

void handleWithParams(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { // Access specific parameter by looping through String unit = "C"; // default value for (int i = 0; i < params.count; i++) { if (String(params.params[i].key) == "unit") { unit = params.params[i].value; break; } } // Use the parameter String response = "Unit selected: " + unit; server.sendResponse(client, response.c_str()); } // URL examples: // /temperature?unit=F // /led?state=on&brightness=50

Hilfsfunktionen für Parameter

Hilfsfunktionen erstellen, um den Zugriff auf Parameter zu erleichtern:

String getParam(const QueryParams& params, const String& key, const String& defaultValue = "") { for (int i = 0; i < params.count; i++) { if (String(params.params[i].key) == key) { return String(params.params[i].value); } } return defaultValue; } bool hasParam(const QueryParams& params, const String& key) { for (int i = 0; i < params.count; i++) { if (String(params.params[i].key) == key) { return true; } } return false; } // Usage in handlers: void handleLed(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { String state = getParam(params, "state", "off"); int brightness = getParam(params, "brightness", "100").toInt(); if (state == "on") { digitalWrite(LED_PIN, HIGH); server.sendResponse(client, "LED turned ON with brightness " + String(brightness)); } else { digitalWrite(LED_PIN, LOW); server.sendResponse(client, "LED turned OFF"); } }

WebSocket-Klassen (eingebaut)

WebSocket-Server
WebSocketServer wsServer(81); // Port 81 for WebSocket

Alias für net::WebSocketServer – vereinfacht für Anfänger.

WebSocket
WebSocket ws;

Alias für net::WebSocket – repräsentiert eine WebSocket-Verbindung.

WebSocket-Methoden
beginnen()
void begin()

Startet den WebSocket-Server.

Schleife()
void loop()

Verarbeiten Sie WebSocket-Ereignisse. Rufen Sie dies in Ihrer Hauptschleife auf.

beiVerbindung()
void onConnection([](WebSocket &ws) { // Handle new WebSocket connection });

Legt den Callback für neue WebSocket-Verbindungen fest.

onMessage()
void onMessage([](WebSocket &ws, const WebSocket::DataType dataType, const char *message, uint16_t length) { // Handle incoming WebSocket message });

Legt einen Callback für eingehende WebSocket-Nachrichten fest.

beimSchließen()
void onClose([](WebSocket &ws, const WebSocket::CloseCode code, const char *reason, uint16_t length) { // Handle WebSocket connection close });

Legt einen Callback für das Schließen von WebSocket-Verbindungen fest.

senden()
void send(const String &message) void send(const char *message, size_t length)

Sendet eine Nachricht über das WebSocket.

schließen()
void close()

Schließt die WebSocket-Verbindung.

Weitere WebSocket-Methoden
broadcastTXT()
void broadcastTXT(const char* payload) void broadcastTXT(const String& payload)

Sendet eine Textnachricht an alle verbundenen WebSocket-Clients.

broadcastBIN()
void broadcastBIN(const uint8_t* payload, size_t length)

Überträgt Binärdaten an alle verbundenen WebSocket-Clients.

verbundeneKunden()
size_t connectedClients()

Gibt die Anzahl der aktuell verbundenen WebSocket-Clients zurück.

istZuhören()
bool isListening()

Gibt true zurück, wenn der WebSocket-Server aktiv auf Verbindungen hört.

WebSocket-Ereignistypen
Datentyp-Enum
  • WebSocket::DataType::TEXT - Textnachrichtentyp
  • WebSocket::DataType::BINARY - Binärdatentyp
CloseCode Aufzählung

Standard-WebSocket-Schließcodes für Gründe der Verbindungsbeendigung.

Fortgeschrittene WebSocket-Nutzung

Einrichtung des Ereignishandlers

void setup() { Serial.begin(9600); // Initialize WiFi and servers WiFi.begin(ssid, password); server.begin(); wsServer.begin(); // Set up WebSocket event handlers wsServer.onConnection([](WebSocket &ws) { Serial.print("Client connected from: "); Serial.println(ws.getRemoteIP()); ws.send("{\"type\":\"welcome\",\"message\":\"Connected to ESP32\"}"); }); wsServer.onMessage([](WebSocket &ws, const WebSocket::DataType dataType, const char *message, uint16_t length) { handleWebSocketMessage(ws, message, length); }); wsServer.onClose([](WebSocket &ws, const WebSocket::CloseCode code, const char *reason, uint16_t length) { Serial.println("Client disconnected"); }); }

Nachrichtenverarbeitung

void handleWebSocketMessage(WebSocket &ws, const char *message, uint16_t length) { String msg = String(message); Serial.println("Received: " + msg); // JSON message handling if (msg.indexOf("\"type\":\"led\"") >= 0) { if (msg.indexOf("\"action\":\"on\"") >= 0) { digitalWrite(LED_PIN, HIGH); ws.send("{\"type\":\"led_status\",\"status\":\"on\"}"); } else if (msg.indexOf("\"action\":\"off\"") >= 0) { digitalWrite(LED_PIN, LOW); ws.send("{\"type\":\"led_status\",\"status\":\"off\"}"); } } // Echo functionality String response = "Echo: " + msg; ws.send(response.c_str()); }

Sensordatenübertragung

void loop() { server.handleClient(); wsServer.loop(); // Broadcast sensor data every 5 seconds static unsigned long lastBroadcast = 0; if (millis() - lastBroadcast > 5000) { if (wsServer.connectedClients() > 0) { float temperature = getTemperature(); String sensorData = "{"; sensorData += "\"type\":\"sensor\","; sensorData += "\"temperature\":" + String(temperature, 1) + ","; sensorData += "\"timestamp\":" + String(millis()); sensorData += "}"; wsServer.broadcastTXT(sensorData); } lastBroadcast = millis(); } }

HTTP-Methoden

Die Bibliothek unterstützt Standard-HTTP-Methoden:

  • HTTP_GET
  • HTTP_POST
  • HTTP_PUT
  • HTTP_DELETE
  • HTTP_PATCH
  • HTTP_HEAD
  • HTTP_OPTIONS

JavaScript-Integration auf der Clientseite

Grundlegende WebSocket-Verbindung

// Connect to ESP32 WebSocket server const ws = new WebSocket('ws://your-esp32-ip:81'); ws.onopen = function(event) { console.log('Connected to ESP32 WebSocket'); document.getElementById('status').textContent = 'Connected'; }; ws.onmessage = function(event) { console.log('Received:', event.data); try { const data = JSON.parse(event.data); handleEsp32Message(data); } catch (e) { // Handle plain text messages console.log('Text message:', event.data); } }; ws.onclose = function(event) { console.log('Disconnected from ESP32'); document.getElementById('status').textContent = 'Disconnected'; // Auto-reconnect after 3 seconds setTimeout(connectWebSocket, 3000); }; ws.onerror = function(error) { console.error('WebSocket error:', error); };

Befehle senden

// Send LED control command function controlLED(action) { if (ws.readyState === WebSocket.OPEN) { const command = { type: 'led', action: action, timestamp: Date.now() }; ws.send(JSON.stringify(command)); } } // Send sensor request function requestSensorData() { if (ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({type: 'get_sensor'})); } }

Nachrichtenverarbeitung

function handleEsp32Message(data) { switch(data.type) { case 'sensor': updateTemperatureDisplay(data.temperature); break; case 'led_status': updateLEDStatus(data.status); break; case 'welcome': console.log('Welcome message:', data.message); break; default: console.log('Unknown message type:', data); } }

WebSocket-Beispiele

Einfacher Echo-Server

wsServer.onMessage([](WebSocket &ws, const WebSocket::DataType dataType, const char *message, uint16_t length) { String response = "Echo: " + String(message); ws.send(response.c_str()); });

JSON-Befehlsverarbeitung

void processWebSocketCommand(WebSocket &ws, const String& message) { if (message.indexOf("\"type\":\"led\"") >= 0) { if (message.indexOf("\"action\":\"on\"") >= 0) { digitalWrite(LED_PIN, HIGH); ws.send("{\"type\":\"led_status\",\"status\":\"on\",\"success\":true}"); } else if (message.indexOf("\"action\":\"off\"") >= 0) { digitalWrite(LED_PIN, LOW); ws.send("{\"type\":\"led_status\",\"status\":\"off\",\"success\":true}"); } } else if (message.indexOf("\"type\":\"get_sensor\"") >= 0) { float temp = getTemperature(); String response = "{\"type\":\"sensor\",\"temperature\":" + String(temp, 1) + "}"; ws.send(response.c_str()); } }

Herzschlag-Implementierung

void setupHeartbeat() { static unsigned long lastHeartbeat = 0; if (millis() - lastHeartbeat > 30000) { // Every 30 seconds if (wsServer.connectedClients() > 0) { String heartbeat = "{\"type\":\"heartbeat\",\"timestamp\":" + String(millis()) + "}"; wsServer.broadcastTXT(heartbeat); } lastHeartbeat = millis(); } }

WebSocket-Fehlerbehebung

Häufige Probleme

WebSocket-Verbindung fehlgeschlagen

  • Stelle sicher, dass der WebSocket-Server-Port (Standard: 81) erreichbar ist
  • Stelle sicher, dass die IP-Adresse des ESP32 korrekt ist und erreichbar ist
  • Verwende die Entwicklertools des Browsers, um WebSocket-Verbindungsfehler zu überprüfen

Nachrichten werden nicht empfangen

  • Überprüfen Sie den seriellen Monitor auf WebSocket-Ereignisprotokolle.
  • Vergewissern Sie sich, dass das JSON-Nachrichtenformat korrekt ist.
  • Testen Sie mit einfachen Textnachrichten, bevor Sie JSON verwenden.
  • Stellen Sie sicher, dass die Länge der Nachricht die Puffergrenzen nicht überschreitet.

Hoher Speicherverbrauch

  • Begrenze die Anzahl gleichzeitiger WebSocket-Verbindungen
  • Leere regelmäßig Nachrichtenpuffer
  • Verwende effiziente String-Verarbeitung (vermeide häufige Verkettung)
  • Überwache den freien Heap-Speicher

Debug-Hilfen

void debugWebSocket() { Serial.println("=== WebSocket Debug Info ==="); Serial.println("Connected clients: " + String(wsServer.connectedClients())); Serial.println("Server listening: " + String(wsServer.isListening() ? "Yes" : "No")); Serial.println("Free memory: " + String(ESP.getFreeHeap()) + " bytes"); Serial.println("Uptime: " + String(millis() / 1000) + " seconds"); Serial.println("============================"); }

Leistungsüberwachung

void monitorPerformance() { static unsigned long lastCheck = 0; static int messageCount = 0; messageCount++; if (millis() - lastCheck > 10000) { // Every 10 seconds Serial.println("Messages/10s: " + String(messageCount)); Serial.println("Clients: " + String(wsServer.connectedClients())); messageCount = 0; lastCheck = millis(); } }

Die Bibliothek unterstützt HTML-Vorlagen mit Platzhalterersetzung:

String response = HTML_TEMPLATE; response.replace("%TEMPERATURE%", String(temperature)); response.replace("%LED_STATUS%", ledStatus ? "ON" : "OFF"); server.send(200, "text/html", response);

Häufige Platzhalter:

  • %TEMPERATURE% - Temperaturwert
  • %LED_STATUS% - LED-Status
  • %QUERY_PARAM% - Abfrageparameter-Werte

Fortgeschrittene Webserver-Funktionen

CORS-Unterstützung

Aktivieren Sie Cross-Origin-Anfragen für Webanwendungen:

// Handle preflight OPTIONS requests server.on("/api/data", HTTP_OPTIONS, []() { server.sendHeader("Access-Control-Allow-Origin", "*"); server.sendHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS"); server.sendHeader("Access-Control-Allow-Headers", "Content-Type"); server.send(200); }); // Add CORS headers to all responses server.sendHeader("Access-Control-Allow-Origin", "*"); server.sendHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); server.sendHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");

Hilfsfunktionen für JSON-Antworten

JSON-API-Entwicklung vereinfachen:

void sendJsonResponse(int statusCode, const String& json) { server.send(statusCode, "application/json", json); } void sendError(int statusCode, const String& message) { String error = "{\"error\":\"" + message + "\"}"; sendJsonResponse(statusCode, error); } // Usage sendJsonResponse(200, "{\"status\":\"success\",\"data\":\"value\"}"); sendError(400, "Invalid request format");

Validierung der Anfrage

Robuste Eingabevalidierung implementieren:

bool isValidJsonAction(const String& action) { return (action == "on" || action == "off" || action == "toggle"); } bool validateRequiredFields(const String& jsonData, const String& field) { return (jsonData.indexOf("\"" + field + "\":") >= 0); } server.on("/api/control", HTTP_POST, []() { if (!server.hasArg("plain")) { sendError(400, "JSON body required"); return; } String body = server.arg("plain"); if (!validateRequiredFields(body, "action")) { sendError(400, "Missing required field: action"); return; } // Process valid request... });

Erweiterte JSON-Verarbeitung

Für die komplexe JSON-Verarbeitung mit der ArduinoJson-Bibliothek:

#include <ArduinoJson.h> void handleJsonRequest() { String requestBody = server.arg("plain"); StaticJsonDocument<200> doc; DeserializationError error = deserializeJson(doc, requestBody); if (error) { sendError(400, "Invalid JSON format"); return; } // Extract values safely const char* action = doc["action"] | "none"; int value = doc["value"] | 0; bool enabled = doc["enabled"] | false; // Create response StaticJsonDocument<200> response; response["status"] = "success"; response["received_action"] = action; response["received_value"] = value; String responseString; serializeJson(response, responseString); sendJsonResponse(200, responseString); }

Fehlerbehandlung

Standard-404-Handler

Die Bibliothek bietet eine Standard-404-Fehlerseite an. Sie können sie überschreiben:

server.onNotFound([]() { server.send(404, "text/html", "<h1>Custom 404 Page</h1>"); });

Beste Praktiken

  1. Speicherverwaltung: Verwenden Sie das F()-Makro für Zeichenketten-Literale, die im Flash-Speicher gespeichert sind
  2. Nicht-blockierender Code: Halten Sie Handler-Funktionen leichtgewichtig, um den Server nicht zu blockieren
  3. Sicherheit: Eingabeparameter validieren und Ausgabe bereinigen
  4. Performance: Verwenden Sie geeignete HTTP-Statuscodes und Content-Typen
  5. WebSocket: Verbindungszustände ordnungsgemäß behandeln und eine Wiederverbindungslogik implementieren

Fehlersuche

Serielles Debugging aktivieren, um die Serveraktivität zu überwachen:

void setup() { Serial.begin(9600); // ... rest of setup } void loop() { server.handleClient(); if (Serial.available()) { String command = Serial.readString(); Serial.println("Debug: " + command); } }

Kompatibilität

  • ESP32: Vollständig unterstützt
  • WiFi-Bibliothek: Erforderlich (im Arduino-IDE enthalten)
  • Speicheranforderungen: Mindestens 32 KB Flash, 2 KB RAM

Einschränkungen

Beschränkungen des Webservers

  • Maximale gleichzeitige HTTP-Verbindungen: 4 (Hardwareeinschränkung)
  • Maximale URL-Länge: 256 Zeichen
  • Vorlagen-Platzhalter: Keine verschachtelten Ersetzungen

WebSocket-Beschränkungen

  • Maximale Größe einer WebSocket-Nachricht: 1 KB pro Nachricht
  • Maximale gleichzeitige WebSocket-Verbindungen: 4–6 (je nach verfügbarem Speicher)
  • Fragmentierte Nachrichten: Automatisch verarbeitet, kann jedoch die Leistung beeinträchtigen
  • Binärnachrichten-Größe: Beschränkt durch den verfügbaren Arbeitsspeicher
  • Verbindungs-Timeout: Standard 60 Sekunden (konfigurierbar)

Speicherbeschränkungen

  • Benötigter Flash-Speicher: 32 KB
  • Benötigter RAM: 2 KB für grundlegende Funktionalität
  • WebSocket-Overhead: ~200–500 Bytes pro Verbindung
  • Nachrichtenpuffer: ~1 KB pro aktive Verbindung

※ UNSERE NACHRICHTEN

  • Sie können gerne den Link zu diesem Tutorial teilen. Bitte verwenden Sie jedoch unsere Inhalte nicht auf anderen Websites. Wir haben viel Mühe und Zeit in die Erstellung der Inhalte investiert, bitte respektieren Sie unsere Arbeit!