Scelte architetturali

 

In questa parte verranno esposte le principali scelte architetturali operate nella fase di design del server.

Come si e’ potuto vedere dai diagrammi di flusso il server principale si deve occupare di quattro azioni fondamentali:

Si e’ deciso che queste operazioni fossero eseguite da altrettanti micro-attori che si occupassero ognuno dell’azione di sua competenza. Questa scelta e’ stata dettata dalla necessita’ di avere un server in grado di gestire piu’ richieste di login contemporaneamente e in cui ogni attore avesse accesso alle proprie risorse e le risorse comuni fossero gestite da un unico attore per evitare conflitti e strutture di sincronizzazione complesse.
Si e’ percio’ progettato un server parallelo con tre threads principali concorrenti e in comunicazione tra di loro, piu’ un quarto (il thread che si occupa del login del client) che viene attivato solo al momento del bisogno.

I quattro micro-attori che formano il nostro sistema sono:


Oltre a questi micro-attori, che sono localizzati tutti all’interno del main server, esistono altri due attori:

Le strutture dati del server sono le seguenti:

Sopra e’ rappresentato uno schema di interazione tra i vari micro-attori. Vediamo di analizzare ora un po’ piu’ in dettaglio le varie comunicazioni.

Sensing Thread <-> Connector Agent

Non si puo’ definire una vera e propria forma di comunicazione. Infatti il Sensing Thread e’ il thread dedicato alla gestione della socket di ascolto ma demanda tutta la comunicazione con il client al Login Thread. E’ stata operata questa divisione dei compiti per poter mantenere un certo parallelismo nella fase del login dei clients.

Login Thread <-> Connector Agent

E’ la parte di login vera e propria. La comunicazione e’ basata sul protocollo di comunicazione TCP perche’ si e’ sentita la necessita’ di avere una comunicazione affidabile e che garantisse la connessione. Infatti il protocollo di login prevede anche l’utilizzo della crittografia, anche se non e’ stata al momento implementata.
La comunicazione avviene con un protocollo in stile piggybacking. Infatti il client che desidera accedere ad una room invia al server un LoginMsg contenente il suo userName, la sua password e la room a cui desidera accedere. Il Login thread controlla che l’utente sia registrato e che esista la room richiesta. Dopodiche’ invia al client un LoginRoomMsg contenente l’IP del leader della room ed eventualmente la password per la comunicazione all’interno della room. Il client, dopo aver ricevuto questo messaggio, invia un messaggio di conferma al server e si mette in contatto con il leader della room.

Rescue Thread <-> Rescue Server

Come si puo’ vedere dal diagramma delle classi, la classe principale e’ il ResqMsg. Questo perche’ si e’ data molta importanza alla comunicazione tra in main server e il rescue server per avere sempre una copia calda a disposizione in caso di crash del server principale. Questa scelta e’ stata sicuramente favorita dalle poche strutture dati presenti nel server (come specifica di progetto si era preso il fatto di avere un server molto leggero, quindi poco interessato dall’evoluzione della room).
La comunicazione tra i due server avviene tramite una socket TCP perche’ si e’ preso come segnale della caduta di un server la mancata risposta da parte di questo ad una richiesta dell’altro server.
Appena stabilita la comunicazione (il main server attiva una socket di ascolto ed accetta la connessione del rescue server) c’e’ una fase preliminare di sincronizzazione tra i due servers costituita dalla trasmissione delle due strutture dati fondamentali (TabRoom e TabPwd) dal main server al rescue server, per far si che i due siamo allineati (copia calda). Poi ad intervalli regolari il main server spedisce dei messaggi (ResqMsg) al rescue server. Questi messaggi possono essere dei semplici messaggi di isAlive per sapere se il server e’ presente, o dei messaggi di modifica delle strutture dati (per far si che il Rescue server sia sempre allineato).
Il sistema e’ stato pensato per sopperire alla caduta di uno dei due server. Se infatti il rescue server cade, il main se ne accorge e si ripone in attesa di una nuova connessione senza inviare nel frattempo alcun messaggio. Se e’ il main server a cadere, il rescue server se ne accorge e avvia un nuovo main server sul suo host.
E’ stata fatta questa scelta perche’ si e’ voluto dare ai client la conoscenza degli IP dei due servers e si e’ voluto evitare che un client, credendo il main server caduto per problemi di ritardo della rete, si rivolgesse al rescue creando due server concorrenti nel soddisfacimento delle richieste di login e non piu’ uno copia calda dell’altro. In questo modo, invece, finche’ il main non e’ caduto, il rescue non e’ abilitato a ricevere richieste di login.