WebSockets - Can't Handle Multiple Instances/Ports?

I’m playing with WebSockets. With a single instance, it works great. But, I want to run multiple instances, on different ports. What has me stumped is that with multiple instances, ALL events get invoked through a single event handler, rather than a different handler for each instance. This makes no sense, and I can’t figure out HOW this is happening…

Here is my quick and dirty test code, based on the WebSockets Server and Client test programs, which creates 4 instances, and sends simple “Ping” and “Pong” messages between client and server. The first thing on each line printed to the Serial port by the event handlers is the instance number, which is ALWAYS 1! Each instance has its own client, its own server, and its own event handler. So how are all events getting passed to the instance 1 event handler??

WebSocketServer.ino

#include <Arduino.h>

#define SERVER

#define NUM_SOCKETS	4

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266mDNS.h> 
#include <Hash.h>

ESP8266WiFiMulti WiFiMulti;

#define USE_SERIAL Serial

boolean Connected = false;


#if defined(SERVER)
#include "WebSocketServer.h"
#else
#include "WebSocketClient.h"
#endif


void setup() {
	USE_SERIAL.begin(115200);

	USE_SERIAL.println();
	USE_SERIAL.println();
	USE_SERIAL.println();

	for (uint8_t t = 4; t > 0; t--)
	{
		USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
		USE_SERIAL.flush();
		delay(1000);
	}

#if defined(SERVER)
	ServerSetup();
#else
	ClientSetup();
#endif
}

void loop() {
    webSocket[0].loop();
	webSocket[1].loop();
	webSocket[2].loop();
	webSocket[3].loop();
#if (NUM_SOCKETS > 4)
	webSocket[4].loop();
#endif
#if (NUM_SOCKETS > 4)
	webSocket[5].loop();
#endif

	if (USE_SERIAL.available())
	{
		char c = USE_SERIAL.read();
		switch (toupper(c))
		{
			case 'D':				
				break;

			case 'C':
				break;

			case 'R':
				break;
		}
	}
}

WebSocketServer.h

#include "WebSocketsServer.h"

WebSocketsServer webSocket[NUM_SOCKETS] =
{
	WebSocketsServer(8001),
	WebSocketsServer(8002),
	WebSocketsServer(8003),
	WebSocketsServer(8004),
#if (NUM_SOCKETS > 4)
	WebSocketsServer(8005),
#endif
#if (NUM_SOCKETS > 5)
	WebSocketsServer(8006),
#endif
};



void ServerSocketEvent(WebSocketsServer &wss, uint8_t port, uint8_t num, WStype_t type, uint8_t * payload, size_t length) {

    switch(type) {

        case WStype_DISCONNECTED:
			{
				if (Connected)
					USE_SERIAL.printf("(%d)[%u] Server Disconnected!\n", port, num);
				Connected = false;
			}
            break;

        case WStype_CONNECTED:
            {
				if (!Connected)
				{
					IPAddress ip = wss.remoteIP(num);
					char s[40];
					sprintf(s, "(%d)%d.%d.%d.%d Connected to Server\n", port, ip[0], ip[1], ip[2], ip[3]);
					USE_SERIAL.printf(s);
#if 0
					wss.sendTXT(num, "Ping");
					USE_SERIAL.printf("(%d)Wrote: Ping\n", port);
#endif
				}
				Connected = true;
            }
            break;

        case WStype_TEXT:
#if 0
			{
				wss.sendTXT(num, payload, length);
			}
#else
			USE_SERIAL.printf("(%d)Read: %s\n", port, payload);
			uint16_t cnt = millis();
			char s[16];
			if (memcmp(payload, "Ping", 4) == 0)
			{
				sprintf(s, "Pong %4x", cnt);
			}
			else
			{
				sprintf(s, "Ping %4x", cnt);
			}
			wss.sendTXT(num, s);
			USE_SERIAL.printf("(%d)Wrote: %s\n", port, s);
#endif
			//delay(2000);
            break;
    }
}


void ServerSocketEvent1(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
	ServerSocketEvent(webSocket[0], 1, num, type, payload, length);
}

void ServerSocketEvent2(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
	ServerSocketEvent(webSocket[1], 2, num, type, payload, length);
}

void ServerSocketEvent3(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
	ServerSocketEvent(webSocket[2], 3, num, type, payload, length);
}

void ServerSocketEvent4(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
	ServerSocketEvent(webSocket[3], 4, num, type, payload, length);
}

#if (NUM_SOCKETS > 4)
void ServerSocketEvent5(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
	ServerSocketEvent(webSocket[4], 5, num, type, payload, length);
}
#endif

#if (NUM_SOCKETS > 5)
void ServerSocketEvent6(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
	ServerSocketEvent(webSocket[5], 6, num, type, payload, length);
}
#endif

void ServerSetup()
{
    WiFiMulti.addAP("TP-LINK_A47DC2", "79517515");

    while(WiFiMulti.run() != WL_CONNECTED) {
        delay(100);
    }

	IPAddress ip = WiFi.localIP();
	USE_SERIAL.printf("Connected to AP as IP=%d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);

    webSocket[0].begin();
    webSocket[0].onEvent(ServerSocketEvent1);
	webSocket[1].begin();
	webSocket[1].onEvent(ServerSocketEvent2);
	webSocket[2].begin();
	webSocket[2].onEvent(ServerSocketEvent3);
	webSocket[3].begin();
	webSocket[3].onEvent(ServerSocketEvent4);
#if (NUM_SOCKETS > 4)
	webSocket[4].begin();
	webSocket[4].onEvent(ServerSocketEvent5);
#endif
#if (NUM_SOCKETS > 5)
	webSocket[5].begin();
	webSocket[5].onEvent(ServerSocketEvent6);
#endif

	//MDNS.begin("WebSocketServer");
}

(Continued…)

Regards,
Ray L.

WebSocketClient.h

#include "WebSocketsClient.h"


WebSocketsClient webSocket[NUM_SOCKETS] =
{
	WebSocketsClient(),
	WebSocketsClient(),
	WebSocketsClient(),
	WebSocketsClient(),
#if (NUM_SOCKETS > 4)
	WebSocketsClient(),
#endif
#if (NUM_SOCKETS > 5)
	WebSocketsClient()
#endif
};


char *ServerIP = "10.0.0.101";
IPAddress ClientIP = IPAddress(10, 0, 0, 108);


void ClientSocketEvent(WebSocketsClient &wsc, uint8_t port, WStype_t type, uint8_t * payload, size_t length)
{

	switch(type) {

		case WStype_DISCONNECTED:
			{
				if (Connected)
					USE_SERIAL.printf("(%d)Client Disconnected!\n", port);
				Connected = false;
			}
			break;

		case WStype_CONNECTED: 
			{
				if (!Connected)
				{
					USE_SERIAL.printf("(%d)Client Connected\n", port);
#if 1
					webSocket[0].sendTXT("Ping");
					webSocket[1].sendTXT("Ping");
					webSocket[2].sendTXT("Ping");
					webSocket[3].sendTXT("Ping");
#if (NUM_SOCKETS > 4)
					webSocket[4].sendTXT("Ping");
#endif
#if (NUM_SOCKETS > 5)
					webSocket[5].sendTXT("Ping");
#endif
#endif
				}
				Connected = true;
			}
			break;

		case WStype_TEXT:
			{
#if 0
				if (memcmp(payload, "Ping", 4) == 0)
				{
					wsc.sendTXT("Pong");
				}
				else
				{
					wsc.sendTXT("Ping");
				}
#else
				USE_SERIAL.printf("(%d)Read: %s\n", port, payload);
				wsc.sendTXT(payload, length);
				USE_SERIAL.printf("(%d)Wrote: %s\n", port, payload);
#endif
			}
			break;
	}
}


void ClientSocketEvent1(WStype_t type, uint8_t * payload, size_t length)
{
	ClientSocketEvent(webSocket[0], 1, type, payload, length);
}


void ClientSocketEvent2(WStype_t type, uint8_t * payload, size_t length)
{
	ClientSocketEvent(webSocket[1], 2, type, payload, length);
}


void ClientSocketEvent3(WStype_t type, uint8_t * payload, size_t length)
{
	ClientSocketEvent(webSocket[2], 3, type, payload, length);
}


void ClientSocketEvent4(WStype_t type, uint8_t * payload, size_t length)
{
	ClientSocketEvent(webSocket[3], 4, type, payload, length);
}

#if (NUM_SOCKETS > 4)
void ClientSocketEvent5(WStype_t type, uint8_t * payload, size_t length)
{
	ClientSocketEvent(webSocket[4], 5, type, payload, length);
}
#endif

#if (NUM_SOCKETS > 5)
void ClientSocketEvent6(WStype_t type, uint8_t * payload, size_t length)
{
	ClientSocketEvent(webSocket[5], 6, type, payload, length);
}
#endif

void ClientSetup() {

	WiFiMulti.addAP("TP-LINK_A47DC2", "79517515");

	//WiFi.disconnect();
	while(WiFiMulti.run() != WL_CONNECTED) {
		delay(100);
	}

	IPAddress ip = WiFi.localIP();
	USE_SERIAL.printf("Connected to AP as IP=%d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);

	// server address, port and URL
	webSocket[0].begin(ServerIP, 8001, "/a");
	webSocket[1].begin(ServerIP, 8002, "/b");
	webSocket[2].begin(ServerIP, 8003, "/c");
	webSocket[3].begin(ServerIP, 8004, "/d");
#if (NUM_SOCKETS > 4)
	webSocket[4].begin(ServerIP, 8005, "/e");
#endif
#if (NUM_SOCKETS > 5)
	webSocket[5].begin(ServerIP, 8006, "/f");
#endif

	// event handler
	webSocket[0].onEvent(ClientSocketEvent1);
	webSocket[1].onEvent(ClientSocketEvent2);
	webSocket[2].onEvent(ClientSocketEvent3);
	webSocket[3].onEvent(ClientSocketEvent4);
#if (NUM_SOCKETS > 4)
	webSocket[4].onEvent(ClientSocketEvent5);
#endif
#if (NUM_SOCKETS > 5)
	webSocket[5].onEvent(ClientSocketEvent6);
#endif

	// use HTTP Basic Authorization this is optional remove if not needed
	//webSocket[0].setAuthorization("user", "Password");

	// try ever 500 again if connection has failed
	webSocket[0].setReconnectInterval(100);
	webSocket[1].setReconnectInterval(100);
	webSocket[2].setReconnectInterval(100);
	webSocket[3].setReconnectInterval(100);
#if (NUM_SOCKETS > 4)
	webSocket[4].setReconnectInterval(100);
#endif
#if (NUM_SOCKETS > 5)
	webSocket[5].setReconnectInterval(100);
#endif

	//MDNS.begin("WebSocketClient");
}

Regards,
Ray L.

BTW - BOTH client and server events are passed to the instance 1 handlers. So, whatever is wrong, is wrong in both the WebSocketsClient and WebSocketsServer.

Regards,
Ray L.

This just got one notch stranger.... I made one, simple change: I made the webSocket arrays for both client and server pointer arrays, with the object created using "new". The events are now being handled, more or less, as expected.

Why on earth would that change make any difference at all??

Regards,
Ray L.