Referencia de la biblioteca WebServer

Visión general

La biblioteca DIYables_ESP32_WebServer ofrece una solución integral para crear servidores web multipágina con soporte de WebSocket en placas ESP32.

Hardware Requerido

1×Módulo de Desarrollo ESP32 ESP-WROOM-32
1×Cable USB Tipo-A a Tipo-C (para PC USB-A)
1×Cable USB Tipo-C a Tipo-C (para PC USB-C)
1×(Recomendado) Placa de Expansión de Terminales de Tornillo para ESP32
1×(Recomendado) Breakout Expansion Board for ESP32
1×(Recomendado) Divisor de Alimentación para ESP32

Or you can buy the following kits:

1×DIYables ESP32 Starter Kit (ESP32 included)
1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)
Divulgación: Algunos de los enlaces proporcionados en esta sección son enlaces de afiliado de Amazon. Podemos recibir una comisión por las compras realizadas a través de estos enlaces sin costo adicional para usted. Apreciamos su apoyo.

Instalación

Pasos R\u00e1pidos

Siga estas instrucciones paso a paso:

  • Si es la primera vez que usas el ESP32, consulta el tutorial sobre configurar el entorno para ESP32 en el IDE de Arduino.
  • Conecta la placa ESP32 a tu computadora usando un cable USB.
  • Inicia el IDE de Arduino en tu computadora.
  • Selecciona la placa ESP32 adecuada (p. ej., ESP32) y el puerto COM.
  • Abre el Administrador de Bibliotecas haciendo clic en el icono de Administrador de bibliotecas ubicado en la parte izquierda del IDE de Arduino.
  • Busca Servidor Web para ESP32 y localiza el mWebSockets de DIYables.
  • Haz clic en el botón Instalar para agregar la biblioteca mWebSockets.
Biblioteca del servidor web ESP32

Soporte de WebSocket (Integrado)

¡La funcionalidad de WebSocket ya está integrada directamente en esta biblioteca!

La implementación de WebSocket se basa en la excelente mWebSockets library by Dawid Kurek, que ha sido integrada y optimizada específicamente para ESP32 para facilitar su uso:

  • No se requiere instalación adicional de bibliotecas - El soporte de WebSocket está integrado
  • Optimizado para ESP32 - Implementación específica de la plataforma simplificada
  • Compatibilidad con WiFi - Utiliza la pila WiFi nativa de ESP32
  • Cumple con RFC 6455 - Soporte completo del protocolo WebSocket
  • Comunicación en tiempo real - Intercambio de datos bidireccional

Uso:

  • Para todo (Servidor Web + WebSocket): Utilice #include <DIYables_ESP32_WebServer.h>
  • ¡Eso es todo! - La funcionalidad de WebSocket está disponible automáticamente cuando sea necesario
  • Eficiente en memoria - El código WebSocket no utilizado se elimina automáticamente por el compilador

Créditos: Implementación de WebSocket adaptada de la biblioteca mWebSockets (Licencia LGPL-2.1) por Dawid Kurek, modificada e integrada para una compatibilidad perfecta con ESP32.

Clases de la biblioteca

Clase DIYables_ESP32_WebServer

La clase principal para crear y administrar servidores web.

Constructor

DIYables_ESP32_WebServer(int port = 80)

Crea una instancia de servidor web en el puerto especificado (predeterminado: 80).

Métodos

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

Inicia el servidor web y comienza a escuchar las conexiones entrantes.

Versiones sobrecargadas:

  • begin(): Iniciar solo el servidor (la red WiFi debe estar conectada separadamente por su aplicación)
  • begin(ssid, password): Conectar a la red WiFi e iniciar el servidor en una sola llamada (enfoque heredado)
setNotFoundHandler()
void setNotFoundHandler(RouteHandler handler)

Configura un manejador personalizado para las respuestas 404 No encontrado.

imprimirEstadoWifi()
void printWifiStatus()

Imprime el estado de la conexión WiFi y la dirección IP en el Monitor Serial.

manejarCliente()
void handleClient()

Procesa las solicitudes entrantes de los clientes. Esto debe llamarse repetidamente en el bucle principal.

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

Registra una función manejadora para una URI específica y un método HTTP.

Parámetros:

  • uri: La ruta URI (p. ej., '/', '/led', '/api/data')
  • method: Método HTTP (GET, POST, PUT, DELETE, etc.)
  • fn: Función manejadora que se ejecuta cuando se accede a la ruta

Nota: Esta biblioteca utiliza el método addRoute() en lugar de on(). Consulte a continuación el uso correcto.

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

Registra una función manejadora para una URI específica. Este es el método real que se utiliza en la biblioteca.

Formato de la función RouteHandler:

Los manejadores de rutas deben seguir esta firma exacta:

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

Parámetros:

  • client: referencia a WiFiClient para enviar respuestas
  • method: método HTTP como cadena de texto ("GET", "POST", etc.)
  • request: URI de la solicitud completa
  • params: Parámetros de consulta (objeto QueryParams)
  • jsonData: carga útil JSON para solicitudes POST (vacía para GET)

Ejemplos de Implementación de Manejadores:

  1. Manejador GET básico:
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); }

i. Manejador de API JSON (GET y 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. Manejador de Parámetros de Consulta:
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); }
enviarRespuesta()
void sendResponse(WiFiClient& client, const char* content, const char* contentType = "text/html")

Envía una respuesta HTTP al cliente.

Parámetros:

  • client: referencia a WiFiClient (proporcionada en la función manejadora)
  • content: contenido del cuerpo de la respuesta
  • contentType: tipo MIME de la respuesta (predeterminado: "text/html")

Ejemplos de uso:

// 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");
Métodos de autenticación
habilitarAutenticacion()
void enableAuthentication(const char* username, const char* password, const char* realm = "ESP32 Server")

Habilita la autenticación HTTP básica para todas las rutas. Una vez habilitada, todas las rutas requieren autenticación.

Parámetros:

  • username: Nombre de usuario para la autenticación (máx. 31 caracteres)
  • password: Contraseña para la autenticación (máx. 31 caracteres)
  • realm: ámbito de autenticación mostrado en el navegador (máx. 63 caracteres, opcional)

Ejemplo de uso:

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

Deshabilita la autenticación, haciendo que todas las rutas sean nuevamente públicas.

Ejemplo de uso:

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

Devuelve verdadero si la autenticación está actualmente habilitada, de lo contrario, falso.

Ejemplo de uso:

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

Envía una respuesta 401 No autorizada con el encabezado WWW-Authenticate adecuado. Esto se invoca automáticamente cuando falla la autenticación, pero se puede usar manualmente en manejadores personalizados.

Ejemplo de uso:

// Manual 401 response in a custom handler server.send401(client);
Envío manual de respuestas

Para un mayor control sobre las cabeceras HTTP y los códigos de estado:

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\"}"); }

Acceso a los parámetros de consulta

Estructura de QueryParams

El objeto QueryParams contiene parámetros de consulta analizados desde la URL:

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

Accediendo a los parámetros de consulta

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

Funciones auxiliares de parámetros

Crear funciones auxiliares para un acceso más fácil a los parámetros:

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"); } }

Clases de WebSocket (integradas)

Servidor WebSocket
WebSocketServer wsServer(81); // Port 81 for WebSocket

Alias para net::WebSocketServer - simplificado para uso de principiantes.

WebSocket
WebSocket ws;

Alias para net::WebSocket - representa una conexión WebSocket.

Métodos de WebSocket
iniciar()
void begin()

Inicia el servidor WebSocket.

bucle()
void loop()

Procesa eventos de WebSocket. Llama a esto en tu bucle principal.

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

Configura un callback para las nuevas conexiones WebSocket.

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

Establece la función de devolución de llamada para los mensajes entrantes de WebSocket.

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

Establece una función de devolución de llamada para los cierres de las conexiones WebSocket.

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

Envía un mensaje a través del WebSocket.

cerrar()
void close()

Cierra la conexión WebSocket.

Métodos adicionales de WebSocket
broadcastTXT()
void broadcastTXT(const char* payload) void broadcastTXT(const String& payload)

Transmite un mensaje de texto a todos los clientes WebSocket conectados.

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

Transmite datos binarios a todos los clientes WebSocket conectados.

clientesConectados()
size_t connectedClients()

Devuelve el número de clientes WebSocket conectados actualmente.

está escuchando()
bool isListening()

Devuelve verdadero si el servidor WebSocket está escuchando activamente las conexiones.

Tipos de eventos de WebSocket
Enumeración de Tipos de Datos
  • WebSocket::DataType::TEXT - Tipo de mensaje de texto
  • WebSocket::DataType::BINARY - Tipo de datos binarios
Enumeración CloseCode

Códigos de cierre estándar de WebSocket para las razones de terminación de la conexión.

Uso avanzado de WebSocket

Configuración del manejador de eventos

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"); }); }

Procesamiento de mensajes

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()); }

Transmisión de datos de sensores

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(); } }

Métodos HTTP

La biblioteca admite los métodos HTTP estándar:

  • HTTP_OBTENER
  • HTTP_ENVIAR
  • HTTP_ACTUALIZAR
  • HTTP_ELIMINAR
  • HTTP_PARCHAR
  • HTTP_CABECERAS
  • HTTP_OPCIONES

Integración de JavaScript del lado del cliente

Conexión WebSocket básica

// 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); };

Enviando comandos

// 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'})); } }

Gestión de mensajes

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); } }

Ejemplos de WebSocket

Servidor de Eco Simple

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

Procesamiento de comandos JSON

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()); } }

Implementación del latido

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(); } }

Solución de problemas de WebSocket

Problemas comunes

Conexión WebSocket fallida

  • Verificar que el puerto del servidor WebSocket (por defecto: 81) sea accesible.
  • Asegurarse de que la dirección IP del ESP32 sea correcta y esté alcanzable.
  • Usar las herramientas de desarrollo del navegador para verificar errores de conexión de WebSocket.

Los mensajes no están siendo recibidos

  • Verificar el Monitor Serial para los registros de eventos de WebSocket
  • Verificar que el formato de los mensajes JSON sea correcto
  • Probar con mensajes de texto simples antes de usar JSON
  • Asegúrese de que la longitud del mensaje no supere los límites del búfer

Alto uso de memoria

  • Limitar el número de conexiones WebSocket concurrentes
  • Limpiar los búferes de mensajes regularmente
  • Usar un manejo eficiente de cadenas (evitar la concatenación frecuente)
  • Monitorear la memoria libre del heap

Herramientas de depuración

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("============================"); }

Monitoreo del rendimiento

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(); } }

La biblioteca admite plantillas HTML con reemplazo de marcadores de posición:

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

Marcadores de posición comunes:

  • %TEMPERATURE% - Valor de la temperatura
  • %LED_STATUS% - Estado del LED
  • %QUERY_PARAM% - Valores de los parámetros de consulta

Características avanzadas del servidor web

Soporte de CORS

Permitir solicitudes de origen cruzado para aplicaciones web:

// 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");

Ayudantes de Respuesta JSON

Simplifica el desarrollo de APIs JSON:

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");

Validación de Solicitudes

Implementar una validación de entradas robusta:

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... });

Procesamiento de JSON mejorado

Para el manejo complejo de JSON con la biblioteca ArduinoJson:

#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); }

Manejo de errores

Manejador 404 por defecto

La biblioteca proporciona una página de error 404 predeterminada. Puedes sobrescribirla:

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

Mejores Prácticas

  1. Gestión de memoria: Utiliza la macro F() para literales de cadena almacenados en memoria flash
  2. Código no bloqueante: Mantén las funciones manejadoras ligeras para evitar bloquear el servidor
  3. Seguridad: Valida los parámetros de entrada y sanea la salida
  4. Rendimiento: Utiliza códigos de estado HTTP apropiados y tipos de contenido
  5. WebSocket: Maneja adecuadamente los estados de conexión e implementa la lógica de reconexión

Depuración

Habilitar la depuración serie para monitorear la actividad del servidor:

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

Compatibilidad

  • ESP32: Completamente soportado
  • Biblioteca WiFi: Requerida (incluida con Arduino IDE)
  • Requisitos de memoria: Mínimo 32KB de flash, 2KB de RAM

Limitaciones

Limitaciones del servidor web

  • Conexiones HTTP simultáneas máximas: 4 (limitación de hardware)
  • Longitud máxima de la URL: 256 caracteres
  • Marcadores de plantilla: Sin reemplazos anidados

Limitaciones de WebSocket

  • Tamaño máximo de mensaje de WebSocket: 1 KB por mensaje
  • Número máximo de conexiones WebSocket concurrentes: 4-6 (dependiendo de la memoria disponible)
  • Fragmentación de mensajes: se gestiona automáticamente, pero puede afectar el rendimiento
  • Tamaño de los mensajes binarios: limitado por la RAM disponible
  • Tiempo de espera de la conexión: 60 segundos por defecto (configurable)

Limitaciones de memoria

  • Memoria flash mínima requerida: 32 KB
  • RAM mínima requerida: 2 KB para la funcionalidad básica
  • Sobrecarga de WebSocket: ~200-500 bytes por conexión
  • Almacenamiento en búfer de mensajes: ~1 KB por conexión activa

※ NUESTROS MENSAJES

  • No dude en compartir el enlace de este tutorial. Sin embargo, por favor no use nuestro contenido en otros sitios web. Hemos invertido mucho esfuerzo y tiempo en crear el contenido, ¡por favor respete nuestro trabajo!