Performance issues with multiple WebSocket connections between ESP8266 and ESP32

Moditest5
Posts: 1
Joined: Thu Oct 30, 2025 11:45 am

Performance issues with multiple WebSocket connections between ESP8266 and ESP32

Postby Moditest5 » Thu Oct 30, 2025 12:00 pm

Hello everyone,

I’m working on a home automation project using several ESP8266 modules together with an ESP32 as a central hub.

Here’s the basic setup:

There are 8 ESP8266 devices installed in my house.

Three of them include a rotary encoder to control the general light brightness.

When an encoder is rotated, that ESP8266 should send a WebSocket message to the other devices so they can adjust their brightness accordingly.

At first, I tried having one ESP8266 act as a “master”, sending WebSocket messages directly to the other 7 devices.
However, it became very slow and was unable to handle encoder pulses properly.

To improve performance, I replaced the master with an ESP32 “central” node, intended to relay messages between the ESP8266 devices.
The ESP32’s only task is to receive a message from one ESP8266 and immediately forward it to the others, without any processing or interpretation.

The architecture looks like this:

Code: Select all

Encoder (ESP8266_1) ---> WebSocket ---> ESP32 (central)
ESP32 (central) ---> WS1 ---> ESP8266_1
                 ---> WS2 ---> ESP8266_2
                 ---> WS3 ---> ESP8266_3
                 ---> ...
                 ---> WS8 ---> ESP8266_8

Unfortunately, I’m still experiencing significant latency.
When I open more than 3 WebSocket connections on the ESP32 and call .loop() for each client, the system becomes almost unresponsive.

My questions:

Is there a better way to manage multiple WebSocket connections efficiently on the ESP32?

Would it be smarter to use a different communication method (like MQTT, UDP broadcast, or something else)?

Any known examples or best practices for this kind of setup?

Any help or suggestions would be greatly appreciated.

Thanks in advance!

The ESP32 code is this, its the bare minimun. With one ws it works good, with 2 its ok, more than that it cant handle it,

Code: Select all

#include <WiFiManager.h>
#include <DNSServer.h>
#include <WebSocketsServer.h>
#include <WebSocketsClient.h>

// ---------------- CONFIGURACIÓN WIFI ----------------
const char ssid[] = "xxxx";
const char pass[] = "xxx";

// ---------------- CLIENTES (otros módulos) ----------------
WebSocketsClient wsRGB;
WebSocketsClient wsCUADRO;
WebSocketsClient wsPC;
WebSocketsClient wsBARRA;
WebSocketsClient wsPIXEL;
WebSocketsClient wsFISCHER;
WebSocketsClient wsCENTRAL;
WebSocketsClient wsCAMA;

// ---------------- IPs y PUERTOS ----------------

const char* wsRGB_ip = "192.168.0.7";
const uint16_t wsRGB_port = 81;
const char* wsCUADRO_ip = "192.168.0.21";
const uint16_t wsCUADRO_port = 82;
const char* wsCAMA_ip = "192.168.0.9";
const uint16_t wsCAMA_port = 83;
const char* wsPC_ip = "192.168.0.10";
const uint16_t wsPC_port = 84;
const char* wsBARRA_ip = "192.168.0.4";
const uint16_t wsBARRA_port = 85;
const char* wsPIXEL_ip = "192.168.0.6";
const uint16_t wsPIXEL_port = 86;
const char* wsFISCHER_ip = "192.168.0.8";
const uint16_t wsFISCHER_port = 87;
const char* wsCENTRAL_ip = "192.168.0.2";
const uint16_t wsCENTRAL_port = 88;

// ---------------- SERVIDOR WEBSOCKET ----------------
const uint16_t wsNUEVACENTRAL_port = 89;
WebSocketsServer wsServer(wsNUEVACENTRAL_port);

// ---------------- PROTOTIPOS ----------------
void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length);
String nombrePorIP(IPAddress ip);

// ---------------- SETUP ----------------
void setup() {
  Serial.begin(115200);
  delay(500);

  Serial.println("\n=== Conectando al WiFi ===");

  WiFi.begin(ssid, pass);
  unsigned long startAttemptTime = millis();

  while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < 10000) {
    Serial.print(".");
    delay(500);
  }

  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("\nNo se pudo conectar, abriendo WiFiManager...");
    WiFiManager wifiManager;
    wifiManager.autoConnect("Domo LEDS", "tucocapo");
  }

  // Inicializo servidor WebSocket
  wsServer.begin();
  wsServer.onEvent(webSocketEvent);
  Serial.printf("Servidor WebSocket iniciado en puerto %u\n", wsNUEVACENTRAL_port);

  // Inicializo clientes WebSocket
  wsRGB.begin(wsRGB_ip, wsRGB_port, "/");
  wsCUADRO.begin(wsCUADRO_ip, wsCUADRO_port, "/");
  wsBARRA.begin(wsBARRA_ip, wsBARRA_port, "/");
  wsPIXEL.begin(wsPIXEL_ip, wsPIXEL_port, "/");
  /*
  wsFISCHER.begin(wsFISCHER_ip, wsFISCHER_port, "/");
  wsCENTRAL.begin(wsCENTRAL_ip, wsCENTRAL_port, "/");
  wsCAMA.begin(wsCAMA_ip, wsCAMA_port, "/");
  wsPC.begin(wsPC_ip, wsPC_port, "/");
  */
}
unsigned long lastLoopCall = 0;
const unsigned long loopInterval = 200;  // 1 segundo
// ---------------- LOOP ----------------
void loop() {
  wsServer.loop();

  //if (millis() - lastLoopCall >= loopInterval) {
    wsRGB.loop();
    lastLoopCall = millis();

    wsCUADRO.loop();
    wsBARRA.loop();
    wsPIXEL.loop();
    // wsFISCHER.loop();
    //wsCENTRAL.loop();
    //wsCAMA.loop();
    //wsPC.loop();
    yield();
  }
}

// ---------------- EVENTOS WEBSOCKET ----------------
void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) {

  switch (type) {

    case WStype_TEXT:
      // Serial.printf("%s (%s): ", nombre.c_str(), ip.toString().c_str());
      // for (size_t i = 0; i < length; i++) Serial.print((char)payload[i]);
      // Serial.println();
      String mensaje = String((char*)payload);
      wsRGB.sendTXT(mensaje);

      break;
  }
}

lbernstone
Posts: 1132
Joined: Mon Jul 22, 2019 3:20 pm

Re: Performance issues with multiple WebSocket connections between ESP8266 and ESP32

Postby lbernstone » Sun Nov 02, 2025 9:07 pm

WebSockets were designed to simplify multiple AJAX requests, where you are asking for the same parameters repeatedly. The expected use is moving chunks of json to a client which is then going to render the data as a time sequence. It keeps sessions open, and does not deal with poor networks very well.
MQTT is designed exactly for your use. It is a keystore with notifications; clients add data, other clients can retrieve that data when notified of changes. I haven't used it, but sMQTTbroker supports QoS 1. There is a ESP-IDF port of mosquitto, which supports tls and other advanced features, but it is in C. You can use a PC as another client to pull all the data off the bus and feed it into an indexed db, if that is how you ultimately want to consume the data.
In any case, remember that this is a small device. If you will be storing any significant amount of data in the broker, you MUST have psram available. You will only be able to service a few requests per second.

Who is online

Users browsing this forum: Qwantbot and 2 guests