allora, paritamo dalle basi:
come avrai notato, il protocollo HTTP è limitato, nel senso che il chliet fa una GET, il server risponde e chiude la connessione. fine. Non esiste modo (se non tramite alcuni artifizi tipo cookie, ma stiamo andando fuori dal seminato) di identificare univocamente un utente, per natura del protocollo HTTP.
Ora, come ben sappiamo il protocollo HTTP però si basa sui socket, che fanno uso del protocollo TCP: il protocollo TCP è monto simile (per il programmatore finale, NON come protocollo in se) come una Seriale: tu hai un oggetto, che una volta inizializzato, scrivi e ricevi byte, fino a che non lo chiudi. Che poi dietro ci sia un cavo USB, Eth o altro poco importa (senza entrare nei particolari).
Qundi ci si è detto: ma è stupido perdere la potenza del protocollo TCP, che è bidirezionale e PERSISTENTE in cambio di un protocollo QUASI MONODIREZIONALE e ONE-SHOT.
Da che sono nati i WebSocket: tu puoi stabilire una comunicazione TCP persistente da una pagina HTML: quindi avrai un solo passaggio da HTTP, e il resto da TCP puro.
Quindi a questo punto hai una modo per parlare alla pagina.
Ora. volessimo passare dei dati basta fare, da entrambe le direzioni, una semplice write/read come faremmo da seriale: sarà poi compito del javascript che riceve capire dovee come inserire il dato ricevuto a sostituzione di quello nuovo modificando gli elementi HTML, o viceversa.
Quindi nasce il problema: cse vogliamo fare una libreria di utilità, essa dovrà essere sia lato arduino per cui tu farai (esempio, è proprio questa struttura che dobbiamo discutere):
WebSocket.print("valore1:");
WebSocket.println(a);
notare che in questo caso ci sono 2 valori speciali: il :, che divide il nome variabile dalla variabile, e il '\n', usato per indicare la fine della variabile. Ciò vuol dire che il nome variabile NON potrà contenere il valore ':', e il valore della variabile non potrà contenere '\n', (quindi se anche solo uno dei byte che compone a vale '\n', l'algoritmo sfasa)
poi ci sarà anche il lato libreria JS, che seguendo uno schema preciso alimenterà un array di array di byte con id stabilito(magari proprio quel 'valore 1' dell'esempio di prima, quindi quel 'valore 1' avrà alte limitazioni dettate dall'HTML, quindi userei un ID numerico preceduto da ID per eliminare ogni problema, es. "ID213"), che conterrano i valori che automagicamentesi aggioreranno, e che saranno "invisibili" (style="display:none;")
Infine quella generata è PARTE della pagina HTML, con solo i div e il javascript; vengono infine incollati in testa e in coda due file tipo inizio.html e fine.html che l'utente può personalizzare;di default conterrano un un semplice script che scorrendo tutti gli array li mostrerà come HEX o come stringa (da decidere) in un div, ne setta la posizione e presenta i dati in maniera "decente". Sta poi all'utente personalizzare come vuole il JS di esempio.
Ora, una (bella secondo me) soluzione è creare una libreria che:
setti varialidi di in/out e RICEVI il rispettivo numero (chepoi sarà l'index nell'array); metti a disposizione get e set di queste variabili. se una variabile è sia in che out basterà settarla sia come in che out.
Notare che tutte le variabili, per semplicità, saranno trattate lato JS e Arduino come Array di BYTE, e lato JS in automatico MOSTRATE come STRINGHE o in HEX, da decidere; In questo modo gli esempi base usarenno le stringe e converitanno i numeri in stringhe, che poi saranno a loro volta inviate alla libreria come array di char, magari nascondendo la cosa; un utentesmaliziato può invece slegarsi dalle stringhe e ottimizzare inviando i byte grezzi.
@pablos: come sei messo a classi in c++? vedo che sai usarle (anche se non lo sai), ma SCRIVERLE? e a puntatori? leo imparò proprio con la sua swRTC a scrivere le classi, e hai visto che fine ha fatto 
btw se invece interessa la via "facile"
WebSocket wsServer0(PREFIX, PORT0);
WebSocket wsServer1(PREFIX, PORT1);
WebSocket wsServer2(PREFIX, PORT2);
WebSocket wsServer3(PREFIX, PORT3);
può diventare pseudocodice eh.. oggi giornata pesante 
WebSocket wsServer[SIZE];
const int PORT_BASE = 9990;
setup(){
for i < SIZE{
wsServer[i] = new wsServer(PREFIX, PORT_BASE+i);//equivale a *alloc() del C
}
}
ATTENTO PERO': hai usato l'allocazione DIANMICA della memoria con la NEW! ciò vuol dire che se ora fai
wsServer[i] = new wsServer(PREFIX, PORT_BASE+i);
la vecchia wsServer RIMANE ad occupare RAM, ma ne hai perso qualsiasi riferimeto, e quindi è ram "bloccata e inutilizzabile": in termine tecnico "garbage", ma il C++ ne il C possiedono un garbage collector. Devi dunque essere TU a rilasciare le risorse:
if (wsServer[i] != null){
delete wsServer[i]; //equivale a free(wsServer[i]); del C
wsServer[i] = null; //assicuriamoci di non usare per sbaglio il riferimento alla variabile che è stata distrutta
}
wsServer[i] = new wsServer(PREFIX, PORT_BASE+i);
In generale, mooooolto meglio se fai le NEW SOLO nel setup, e poi gli oggetti li usi ma non li "distruggi", eviti TAAANTI sbattimenti.