• Non ci sono risultati.

Comunicazioni tra peer

Figura 4.3: Classe JadeEvent ˆ Inizializzazione metodo per l'invio/ricezione di messaggi. ˆ Avvio thread invio e ricezione messaggi di heartbeat.

Quest'ultimo aspetto è cruciale in quanto una parte consistente del traco di rete è generato proprio dai messaggi di heartbeat scambiati tra i peer.

Ricordiamo che ogni peer invia un messaggio di heartbeat ogni 200 millisecondi. Nella sezione successiva si descrive l'implementazione di diverse tecniche per l'invio e ricezione dei messaggi di heartbeat tra peer; nel capitolo 5 vengono presentate alcune valutazioni a riguardo.

4.4 Comunicazioni tra peer

4.4.1 Eventi

Il supporto JaDE si colloca come un layer intermedio tra un'applicazione GUI per un DVE e una rete di comunicazione (v. sezione 3.4): dalla rete si ricevono messaggi

Figura 4.4: Creazione di un messaggio

provenienti dagli altri peer che devono essere noticati alla GUI come eventi remoti. Dalla GUI arrivano eventi generati dal peer locale che devono essere comunicati agli altri partecipanti attraverso la rete.

La classe JadeEvent (v. gura 4.3) rappresenta questo tipo di eventi.

In base al tipo di evento ricevuto dal layer GUI si invia in rete un messaggio con un formato specico. Come mostrato nel codice Java della gura 4.4 il messaggio contiene le informazioni che permettono di identicare il peer che ha generato l'e- vento (identicatore unico e nome), le informazioni riguardanti l'evento (coordinate (x,y,z) dello spazio e il tipo di evento) e il timestamp relativo alla creazione del messaggio.

4.4.2 Tecniche di invio messaggi heartbeat

In questa sezione si presentano tre diverse implementazioni per la gestione dei mes- saggi di heartbeat tra i peer. Una prima soluzione si basa sull'utilizzo di una propa- gate pipe; la seconda tecnica sfrutta il Resolver Protocol come mezzo di propagazione dei messaggi all'interno del gruppo; la terza soluzione è implementata attraverso i peer advertisement del Discovery Protocol.

4.4. COMUNICAZIONI TRA PEER 103 Propagate pipe

La JXTA propagate pipe è uno strumento di comunicazione asimmetrica che con- sente lo scambio di informazioni secondo lo schema molti-a-molti (v. capitolo 2 sezione2.2), quindi ideale per la comunicazione dell'heartbeat da un peer verso tutti gli altri peer della regione.

Ad ogni peer group di una regione si associa una propagate pipe. Ogni peer per utilizzare la pipe deve ottenere il relativo JXTA advertisement; a tal proposito ci sono due possibili soluzioni:

ˆ Il primo peer che si connette alla regione crea l'advertisement per la pipe e lo pubblica nell'ambito del gruppo; i peer che successivamente si connetteranno al gruppo, e vorranno utilizzare la pipe devono eseguire una ricerca attraverso il Discovery Protocol per ottenere l'advertisement.

ˆ L'advertisement della pipe viene generato prima dell'esecuzione dell'applica- zione e memorizzato in un le con estensione .adv; il le viene distribuito a tutti i partecipanti insieme al pacchetto di installazione del software. Tale soluzione permettere al peer di utilizzare immediatamente la propagate pipe, eliminando i tempi di ricerca che si invece di devono sostenere nella prima soluzione.

Utilizziamo la seconda soluzione per i vantaggi che comporta.

La propagate pipe sarà aperta sia in lettura che in scrittura da ogni peer che fa parte del gruppo:

ˆ In lettura: ogni peer della regione apre la pipe in lettura; dunque si ricevono i messaggi di heartbeat provenienti dai peer della regione. Ad ogni messaggio ricevuto si aggiorna la struttura dati che contiene i vicini conosciuti inserendo il timestamp corrispondente alla ricezione del messaggio di heartbeat.

ˆ In scrittura: ogni 200 millisecondi si invia sulla pipe un messaggio di heartbeat secondo il formato indicato nella gura 4.4. In messaggio sarà ricevuto da tutti i peer della regione.

Il thread per la gestione della propagate pipe è rappresentato dalla classe Pro- pagationPipeListener, interna alla classe PeerDve. Questa classe implementa l'in- terfaccia PipeMsgListener e fornisce l'implementazione del metodo pipeMsgEvent(), invocato ogni volta che si riceve un nuovo messaggio dalla propagate pipe.

La propagate pipe non è un mezzo di comunicazione adabile, cioè non assicura che il messaggio venga eettivamente recapitato al destinatario.

Date le modalità e lo scopo dell'utilizzo del canale possiamo tollerare la perdita di alcuni messaggi senza perdere la consistenza della overlay network1; più avanti

nella trattazione incontreremo casi in cui l'adabilità del canale rappresenta un vincolo e si utilizzeranno altri strumenti.

Resolver Protocol

Il Peer Resolver Protocol permette ad un peer di inviare richieste generiche ai peer del gruppo di cui è membro e di ricevere le relative risposte alla query. In questo caso il Resolver Protocol viene utilizzato solo come mezzo di propagazione di messaggi di heartbeat nel gruppo; i peer che ricevono la query non devono inviare nessuna risposta.

Le query possono avere qualsiasi formato quindi possiamo inviare attraverso il Resolver Protocol un messaggio con formato xml mostrato nella gura 4.4 utiliz- zando però la classe net.jxta.document.StructuredTextDocument invece della classe net.jxta.endpoint.Message, utilizzata per l'invio del messaggio su pipe.

La gestione dei messaggi attraverso il Resolver Protocol richiede la denizione di un handler che implementi l'interfaccia net.jxta.resolver.QueryHandler; a tale sco- po introduciamo la classe ResolverQueryHandler del package jxtaPeer che fornisce l'implementazione dei metodi processQuery() e processResponse():

ˆ processQuery() viene invocato ogni volta che si riceve un messaggio dal Resol- ver Protocol; alla ricezione di un messaggio di heartbeat si aggiorna la struttura dati che contiene i vicini conosciuti inserendo il timestamp corrispondente alla

1In applicazioni real-time si applica la tecnica del Dead Reckoning per prevedere le posizioni

che assumeranno i peer remoti qualora i messaggi di notica delle loro posizioni (heartbeat) siano soggetti a ritardi

4.4. COMUNICAZIONI TRA PEER 105 ricezione del messaggio. In generale il Resolver Protocol prevede che il peer invii una risposta, in questo caso non occorre.

ˆ il metodo processResponse() viene invocato ogni volta che si riceve una risposta a seguito di una query; poichè nel nostro caso non è prevista una risposta il corpo del metodo è vuoto.

Il corretto funzionamento del Resolver Protocol richiede che l'handler venga regi- strato con il metodo registerHandler() di net.jxta.protocol.ResolverService. Il me- todo sendEvent() della classe PeerDve provvede ad eseguire l'invio dei messaggi attraverso il Resolver Protocol.

Discovery Protocol

Il Discovery Protocol è uno dei protocolli core di JXTA; permette di scoprire le risorse presenti nella rete: peer, peer group, advertisement, etc; in questo caso siamo interessati alla scoperta dei peer di un certo gruppo.

JXTA ore due tecniche di scoperta di risorse:

ˆ Invocare il metodo getRemoteAdvertisements(); attendere che uno o più peer rispondano; accedere alla cache locale con il metodo getLocal

Advertisements() per recuperare gli advertisement che sono stati inseriti nella cache a seguito della richiesta; per scoprire nuove risorse occorre invocare di nuovo il metodo getRemoteAdvertisements().

ˆ Invocare il metodo getRemoteAdvertisements() passando come parametro un listener dell'interfaccia net.jxta. discovery .DiscoveryListener; lo scopo del listener è invocare il metodo callback discoveryEvent() ogni volta che si riceve un evento di scoperta nuova risorsa. Questa soluzione permette di ricevere in maniera asincrona i peer advertisement.

Il thread NeighbourDiscovery (classe interna della classe PeerDve) utilizza la seconda soluzione proposta per la scoperta dei peer vicini e per la rilevazione di peer non più attivi o falliti. Il thread invia ogni 200 millisecondi un richiesta di scoperta di peer con il metodo discovery. getRemoteAdvertisements (null,DiscoveryService.PEER,

null, null, 0) registrando il thread NeighbourDiscovery come listener per gli eventi di tipo DiscoveryEvent.

I peer della regione ricevendo la richiesta invieranno una DiscoveryResponseMsg che permette al peer richiedente di conoscere se i suoi vicini sono ancora attivi. Ogni volta che si riceve un evento DiscoveryEvent si aggiorna la struttura dati che contiene i vicini conosciuti inserendo il timestamp corrispondente alla ricezione dell'evento.

L'utilizzo dei JXTA peer advertisement non permette di introdurre altre infor- mazioni che sono necessarie, come le coordinate del peer nello spazio. Dunque questa terza soluzione fornisce un meccanismo di keep alive per i peer dell'ambiente virtua- le che permette di sapere se e quando un peer abbandona una regione. Per inviare informazioni aggiuntive occorre adottare un metodo di invio di messaggi come quelli descritti sopra.

Ognuna delle tre soluzioni che sono state appena descritte gestisce anche la rile- vazione dei peer non più attivi o che hanno abbandonato la regione: ad intervalli di tempo regolari si accede alla struttura dati che contiene i peer vicini; per ogni vicino si confronta il timestamp dell'ultimo heartbeat ricevuto con il timestamp dell'istante corrente; se l'intervallo di tempo trascorso è maggiore di ALIVE_TIMEOUT = 10 secondi allora il peer vicino viene eliminato della struttura dati e non più considerato come vicino.