Le classi di Archivio Client-Server

Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Organizzazione della lezione
Lezione 16
Remote Method Invocation - 4
Vittorio Scarano
Corso di Programmazione Distribuita (2003-2004)
Laurea di I livello in Informatica
Università degli Studi di Salerno
• Alcuni esempi di applicazioni distribuite:
– una agenda telefonica distribuita (client-server)
– una chat (client-server)
• Alcuni commenti sul ruolo del registry
– una chat (peer-to-peer)
2
• Modello più comune
• Il Client effettua una
richiesta
– Es.: invocazione remota
• Il server invia la risposta
– Es.: risultato della invocazione
Le classi di Archivio Client-Server
client
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Modello Client Server
client
request
response
server
• Un esempio di applicazione
– una agenda telefonica
– ogni client può:
• registrare un numero telefonico
• richiedere la lista di tutti i numeri
inseriti
3
4
Le classi di Archivio Client-Server
import java.rmi.*;
import java.util.*;
public interface Server
extends java.rmi.Remote {
public void registra (RecordAgenda r)
throws RemoteException;
public ArrayList dammiAgenda ()
throws RemoteException;
}
• Import
• Interfaccia remota
• Due metodi remoti
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Server.java
ದ UHJLVWUD
• inserisce il record
passato nella lista
ದ GDPPL$JHQGD
• lettura completa della
Agenda
5
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
public RecordAgenda(String n, String t, String i){
nome = n;
telefono = t;
inseritoDa = i;
}
public String getNome() {return nome; }
public String getTelefono() {return telefono; }
public String getInseritoDa() {return inseritoDa;}
• Serializzabile
– deve essere trasmessa
come parametro
• Costruttore
• Metodi di accesso
• Variabili istanza
private String nome;
private String telefono;
private String inseritoDa;
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Le classi di Archivio Client-Server
RecordAgenda.java
public class RecordAgenda
implements java.io.Serializable {
6
}
7
8
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
import java.io.*;
public class ServerImpl
extends UnicastRemoteObject
implements Server {
public ServerImpl()
throws java.rmi.RemoteException { }
public static void main(String args[]) {
System.setSecurityManager(
new RMISecurityManager());
try {
ServerImpl obj = new ServerImpl();
Naming.rebind("AgendaServer", obj);
System.out.println("Pronto..");
} catch (Exception e) {
e.printStackTrace();
}
} // end main … Continua…
ServerImpl.java (2)
• Import di vario uso
• Oggetto remoto
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
ServerImpl.java (1)
– che implementa la
interface Server
ವ PDLQ
– Security Manager
– registrazione sul
registry
public ArrayList dammiAgenda ()
throws RemoteException{
return agenda;
}
• Metodi remoti
ವ UHJLVWUD
– aggiunge ad agenda
– stampa a video
ವ GDPPL$JHQGD
– restituisce l’ArrayList
• Variabile istanza
– con inizializzazione
private ArrayList agenda = new ArrayList();
}
9
Le classi di Archivio Client-Server
public void registra (RecordAgenda r)
throws RemoteException{
agenda.add(r);
System.out.println ("Inserito record:"+
r.getNome()+
" Num.: "+
r.getTelefono()+
" Inserito da: "+
r.getInseritoDa());
}
10
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
ClientAgenda.java (1)
11
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
import java.io.*;
public class ClientAgenda {
public static void main(String args[]) {
Server serverRef = null;
if (args.length > 0 ) nickname = args[0];
else {System.out.println (“Dare il nickname");
System.exit(1);
}
System.setSecurityManager(
new RMISecurityManager());
try {
serverRef = (Server) Naming.lookup (
"rmi://"+HOST+"/AgendaServer");
} catch (Exception e) {
e.printStackTrace();
}
// continua…
• Import di vario uso
ವ PDLQ
– lettura del nickname
• con errore se non c’è
– Security Manager
– ricerca del server su
registry
12
// sempre nel main.. la shell
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
String cmd;
System.out.println ("Benvenuto "+nickname);
for (;;) {
System.out.print(PROMPT);
cmd = in.readLine();
if (cmd.equals ("close")) {
break;
} else if (cmd.equals("inserisci")) {
System.out.print ("Nome: ");
String nome = in.readLine();
System.out.print ("Telefono: ");
String telefono = in.readLine();
RecordAgenda r = new RecordAgenda(
nome, telefono, nickname);
serverRef.registra(r);
} else if (cmd.equals("lista")) {
ClientAgenda.java (3)
• La shell di comandi
del client
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
ClientAgenda.java (2)
– Comandi:
• close/inserisci/lista
– apertura stream
• Uscita
• Inserimento
– lettura parametri
– invocazione metodo
remoto sul server
13
• In questa applicazione, il ruolo del client e del server
sono rigidamente fissati
– il client “chiede” (invoca) ed il server “dà” (restituisce)
• Non sempre questo è possibile
– in applicazioni più evolute (anche di poco), il client deve
essere contattato dal server
– se non altro, per favorire la “consapevolezza” (awareness)
dell’utente sul comportamento degli altri
• ad esempio, vorremmo informare un utente su chi è connesso in
questo momento
• Necessario il call-back
• Lista dei record
inseriti
– invocazione remota
– stampa di tutti i record
• Comando non
compreso
• Variabile di istanza
• Costante di uso
14
Il call-back
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Alcuni commenti
// sempre nel main.. e nel for…
else if (cmd.equals("lista")) {
ArrayList a = serverRef.dammiAgenda();
for (int i = 0; i < a.size(); i++) {
RecordAgenda rec=(RecordAgenda)a.get(i);
System.out.println (rec.getNome()+ " "+
r.getTelefono()+" (inserito da "+
rec.getInseritoDa()+")");
}
} else System.out.println ("UH?");
}// fine for
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}// fine main
static String nickname;
public static final String HOST=“localhost";
public static final String PROMPT="Comandi >";
}
15
• Meccanismo mediante il quale il client chiede al server
di essere richiamato (call-back)
• Una altra motivazione (oltre alla consapevolezza)
– chiamate asincrone per la la richiesta di un servizio
“pesante” computazionalmente
• il client richiede un servizio e chiede di essere richiamato quando i
risultati sono disponibili
• Implementazione con Invocazioni Remote
– il client (dotato di interface remota) passa il proprio
riferimento remoto al server che lo usa per contattarlo
• I ruoli di client e server non vengono scambiati
– non è un peer-to-peer
16
Una applicazione client-server evoluta
• Alcuni esempi di applicazioni distribuite:
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Organizzazione della lezione
– una agenda telefonica distribuita (client-server)
– una chat (client-server)
• Alcuni commenti sul ruolo del registry
– una chat (peer-to-peer)
• Una chat “classica” ma semplice (IRC dei poveri)
• Il server
– riceve da ogni client la iscrizione/abbandono della chat
– manda a tutti i client quello che ognuno dice (broadcast)
• La necessità del call-back
– implicita nella applicazione: il server deve poter informare
ogni client di quanto digitato da un client
– ma anche necessaria per permettere ad ogni utente di avere
la informazione su chi è iscritto alla chat
17
Le classi di Chat Client-Server
18
Server.java
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
import java.rmi.*;
19
public interface Server
extends java.rmi.Remote {
public void dico (Messaggio m)
throws RemoteException;
public void iscrivi (Remote idRef)
throws RemoteException;
public void abbandona (Remote idRef)
throws RemoteException;
}
• Import
• Interfaccia remota
• Tre metodi remoti
ದ GLFR
• chiamato da un client se
deve scrivere a tutti
ದ LVFULYL
• iscrizione alla chat
ದ DEEDQGRQD
• per abbandonare
• Notare il passaggio del
riferimento remoto
necessario per il call- 20
back
Le classi di Chat Client-Server
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Chat.java
import java.rmi.*;
public interface Chat
extends java.rmi.Remote {
public void dico (Messaggio m)
throws RemoteException;
public void iscrivi (String nickIscritto)
throws RemoteException;
public void abbandona (String nickAbbandona)
throws RemoteException;
public String getNickname ()
throws RemoteException;
• Interfaccia remota
• Quattro metodi remoti
ದ GLFR
• chiamato dal server per il
broadcast di messaggi
ದ LVFULYLDEEDQGRQD
• consapevolezza della
iscrizione/abbondono alla
chat di un utente
ದ JHW1LFNQDPH
• utilità per uso da parte del
server (non fondamentale)
}
• Metodi chiamati solo dal
server
21
Le classi di Chat Client-Server
22
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Messaggio.java
23
public class Messaggio
implements java.io.Serializable{
private String mittente;
private String testo;
public Messaggio(String mit, String tes) {
mittente = mit;
testo = tes;
}
public String getMittente() {
return mittente;
}
• I dati spediti come
parametri ai metodi
– necessario serializzarli
• Variabili istanza
• Costruttore
• Metodi di accesso
public String getTesto() {
return testo;
}
}
24
Le classi di Chat Client-Server
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
ServerImpl.java (1)
25
public void iscrivi (Remote idRef)
throws RemoteException {
String nomeClientIscritto =
((Chat) idRef).getNickname();
System.out.println ("\nEntra "+
nomeClientIscritto+".");
// Notifica a tutti i client presenti
for (int i = 0; i < clientRefs.size(); i++) {
Chat unClient = ((Chat) clientRefs.get(i));
unClient.iscrivi(nomeClientIscritto) ;
}
clientRefs.add(idRef);
}
// continua
• Import di vario uso
• Oggetto remoto
– che implementa la
interface Server
ವ PDLQ
– Security Manager
– registrazione sul
registry
26
ServerImpl.java (3)
• Metodo LVFULYL
– si preleva il nickname
– si notifica a tutti i
client in lista
• notare che il client
appena iscritto non è
ancora nella lista
– aggiunta alla lista di
client connessi
• si usa il riferimento
remoto
27
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
ServerImpl.java (2)
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
import java.io.*;
public class ServerImpl
extends UnicastRemoteObject
implements Server {
public ServerImpl()
throws java.rmi.RemoteException { }
public static void main(String args[]) {
System.setSecurityManager(
new RMISecurityManager());
try {
ServerImpl obj = new ServerImpl();
Naming.rebind("ChatServer", obj);
System.out.println("Pronto …");
} catch (Exception e) {
e.printStackTrace();
}
} // end main… Continua
public void abbandona (Remote idRef)
throws RemoteException {
int indice = clientRefs.indexOf(idRef);
Object app = clientRefs.remove(indice);
String nomeClientAbbandona =
((Chat) idRef).getNickname();
System.out.println ("\n"+
nomeClientAbbandona +
" ha abbandonato la chat.");
// Invio la notifica a tutti i client
for (int i = 0; i < clientRefs.size(); i++) {
Chat unClient = ((Chat) clientRefs.get(i));
unClient.abbandona(nomeClientAbbandona);
}
• Metodo DEEDQGRQD
– speculare a iscrivi
– cancellazione
• preleva l’indice
nell’ArrayList a cui è
memorizzato il client
• lo cancella
– notifica
• come per LVFULYL
}
28
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
public void dico (Messaggio m)
throws RemoteException {
for (int i = 0; i < clientRefs.size(); i++) {
Chat unClient = ((Chat) clientRefs.get(i));
// invio a tutti tranne che al mittente
if ( ! (m.getMittente().equals(
unClient.getNickname())))
unClient.dico(m) ;
}
}
static ArrayList clientRefs = new ArrayList();
}
• Metodo GLFR
– per ogni client
• se non è il mittente del
messaggio
• invia il messaggio al
client
• Variabile istanza per i
client
– contiene i riferimenti
remoti dei client
– inizializzazione
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Le classi di Chat Client-Server
ServerImpl.java (4)
29
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
import java.io.*;
public class ChatImpl
extends UnicastRemoteObject
implements Chat {
public ChatImpl()
throws java.rmi.RemoteException { }
public static void main(String args[]) {
ChatImpl myself = null;
Server serverRef = null;
if (args.length > 0 ) nickname = args[0];
else{ System.out.println (“Serve nickname");
System.exit(1);
}
System.setSecurityManager(
new RMISecurityManager());
// continua
ChatImpl.java (2)
• Import di vario uso
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
ChatImpl.java (1)
30
ವ PDLQ
– lettura del nickname
• con errore se non c’è
– Security Manager
31
try {
serverRef = (Server) Naming.lookup (
"rmi://"+HOST+"/ChatServer");
myself = new ChatImpl();
serverRef.iscrivi (myself);
} catch (Exception e) {
e.printStackTrace();
}
// Shell
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
String cmd;
System.out.println ("Benvenuto "+nickname);
• Ricerca del server
• Registrazione sul
server della chat
• Preparazione per la
shell
– stream di input
– string adi benvenuto
// continua
32
• Loop della shell
– se si abbandona
• informa il server
– altrimenti si tratta di
un messaggio per il
server (per tutti)
• costruzione messaggio
• invio al server
– che si occuperà di
farne il broadcast
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
• Metodi remoti
public void iscrivi (String nickIscritto)
throws RemoteException{
System.out.print ("\nEntra "+nickIscritto+"."+
"\n"+PROMPT);
}
ವ GLFR
// continua
ವ LVFULYL
– di uso principalmente per
la consapevolezza degli
altri utenti e per l’output
– stampa a video (mittente e
testi) e poi ristampa il
prompt
– stampa a video e ristampa
il prompt
34
Organizzazione della lezione
public void abbandona (String nickAbbandona)
throws RemoteException {
System.out.print ("\n"+nickAbbandona+
" ha abbandonato la chat"+"\n"+PROMPT);
}
• Altri metodi remoti
ವ DEEDQGRQD
public String getNickname ()
throws RemoteException {
return nickname;
}
ವ JHW1LFNQDPH
public static final String HOST=“localhost";
public static final String PROMPT = "Comandi >";
}
public void dico (Messaggio m)
throws RemoteException {
System.out.print ("\n"+m.getMittente()+": "+
m.getTesto()+"\n"+PROMPT);
}
33
ChatImpl.java (5)
static String nickname;
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
for (;;) {
System.out.print(PROMPT);
cmd = in.readLine();
if (cmd.equals ("close")) {
serverRef.abbandona (myself);
break;
} else { // messaggio per tutti
if (cmd.length() !=0) {// stringa non vuota
Messaggio m = new
Messaggio (nickname, cmd);
serverRef.dico(m);
}
}
}// fine for
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}// fine main
// continua
ChatImpl.java (4)
– stampa a video e ristampa
il prompt
– metodo di accesso
• Variabile di istanza
• Costanti di uso
35
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
ChatImpl.java (3)
• Alcuni esempi di applicazioni distribuite:
– una agenda telefonica distribuita (client-server)
– una chat (client-server)
• Alcuni commenti sul ruolo del registry
– una chat (peer-to-peer)
36
La architettura della Chat P2P
• La architettura Client-Server della Chat
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Commenti sulla architettura della Chat
– offre un singolo punto di “debolezza” (il server)
– non risponde alla struttura del problema
• in effetti, ogni client deve poter inviare a ciascun altro client
• serve solamente poter sapere chi sono i client registrati
• Possibile passare ad una architettura Peer-to-peer
– dove l’unica componente centralizzata è il registry
• che deve necessariamente essere presente (comunque) anche sulla
architettura client-server
• Ogni peer
trasmette i
messaggi a tutti
gli altri peer
• Si usa il registry
per avere
informazioni su
chi è registrato
alla chat
application
coordination
code
application
application
coordination
code
coordination
code
37
• Per ogni applicazioni peer-to-peer è comunque sempre
necessario una componente che permetta il bootstrap:
– “locazione” fissata per poter contattare gli altri peer
• Nel caso di RMI si può usare il registry
– tramite il metodo list() è possibile sapere tutti gli id
(stringhe) degli oggetti remoti registrati
– a partire da cui si può ottenere il riferimento remoto
– che può essere usato per contattare gli oggetti
(discriminando, se è il caso, rispetto alle interface
implementate)
• se sul registry stanno in esecuzione diverse applicazioni distribuite39
Le classi di Chat P2P
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Il ruolo del registry nelle applicazioni P2P
38
40
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
import java.rmi.*;
public interface Chat
extends java.rmi.Remote {
public void dico (Messaggio m)
throws RemoteException;
public void iscrivi (String id)
throws RemoteException;
public void abbandona (Remote idRef)
throws RemoteException;
public String getNickname ()
throws RemoteException;
}
• Interfaccia remota
• Quattro metodi remoti
ದ GLFR
• chiamato da un altro peer per
scrivere un messaggio
ದ LVFULYLDEEDQGRQD
• inserimento o cancellazione
nella lista dei peers che
ognuno ha
ದ JHW1LFNQDPH
• utilità per uso da parte degli
altri peers (non
fondamentale)
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Le classi di Chat P2P
Chat.java
41
Le classi di Chat P2P
public String getMittente() {
return mittente;
}
public String getTesto() {
return testo;
}
• Identica al programma
precedente
• I dati spediti come
parametri ai metodi
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Messaggio.java
public class Messaggio
implements java.io.Serializable{
private String mittente;
private String testo;
public Messaggio(String mit, String tes) {
mittente = mit;
testo = tes;
}
42
– necessario serializzarli
• Variabili istanza
• Costruttore
• Metodi di accesso
}
43
44
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
import java.io.*;
public class ChatImpl
extends UnicastRemoteObject
implements Chat {
public ChatImpl()
throws java.rmi.RemoteException { }
public static void main(String args[]) {
Chat myself = null;
if (args.length > 0 ) nickname = args[0];
else {
System.out.println (“Serve il nickname");
System.exit(1);
}
System.setSecurityManager(
new RMISecurityManager());
ChatImpl.java (2)
• Import di vario uso
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
ChatImpl.java (1)
ವ PDLQ
– lettura del nickname
• con errore se non c’è
– Security Manager
45
// continua….
try { // Shell nel main
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
String cmd;
System.out.println ("Benvenuto "+nickname+
". Con te sono presenti "+
peers.size()+" utenti:");
for (int i = 0; i < peers.size(); i++)
System.out.println ("\t"+
((Chat) peers.get(i)).getNickname() );
for (;;) {System.out.print(PROMPT);
cmd = in.readLine();
if (cmd.equals ("close")) {
for (int i = 0; i < peers.size(); i++)
((Chat) peers.get(i)).abbandona(myself);
break;
} else { // continua
myself = new ChatImpl();
Naming.rebind(nickname, myself);
System.out.println (“Informo tutti…:");
for (int i=0 ; i < nomi.length; i++) {
System.out.print ("\tIscrizione a "+
(Chat) peers.get (i)).getNickname()+"..") ;
((Chat) peers.get (i)).iscrivi (nickname) ;
System.out.println ("effettuata!");
}
} catch (Exception e) {e.printStackTrace(); }
// continua…
• Ottiene l’elenco del
nome dei peer connessi
dal registry
– li stampa
• Costruisce l’arrayList dei
riferimenti remoti
connessi
• Si registra sul registry
• Si iscrive presso ogni
peer
– invocazione remota di
iscrivi()
46
ChatImpl.java (4)
• Apertura stream input
• Stampa degli utenti
connessi
• Loop della shell
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
ChatImpl.java (3)
try { // Fase di Registrazione nel main
String nomi[] = Naming.list("rmi://"+HOST);
System.out.println (
“Sono connessi "+nomi.length+" utenti:");
for (int i=0 ; i < nomi.length; i++)
System.out.println ("\t"+nomi[i]);
for (int i=0 ; i < nomi.length; i++)
peers.add(Naming.lookup (nomi[i]));
– se si esce, comunico a
tutti i peers il mio
Riferimento remoto
• uso la variabile myself
47
} else { // si tratta di un messaggio da inviare a tutti
if (cmd.length() !=0) { // stringa non vuota
for (int i = 0; i < peers.size(); i++) {
Messaggio m = new Messaggio (
nickname, cmd);
((Chat) peers.get(i)).dico(m) ;
}
}
}
}// fine for
} catch (Exception e) {
e.printStackTrace();
}
try {Naming.unbind(nickname);
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}// fine main
• Invio la stringa a tutti i
peers di cui sono a
conoscenza
• In uscita dal main,
rimuovo il mio
riferimento dal registry
• … e mi suicido!
48
ChatImpl.java (6)
public void dico (Messaggio m)
throws RemoteException {
System.out.print ("\n"+m.getMittente()+": “
+m.getTesto()+"\n"+PROMPT);
}
• Metodi remoti:
public void iscrivi (String id)
throws RemoteException {
try {
peers.add(Naming.lookup (
"rmi://"+HOST+"/"+id));
} catch (Exception e) {
e.printStackTrace();
}
System.out.print ("\nEntra "+id+".“
+"\n"+PROMPT);
}
ವ GLFR
– in generale stampano
informazioni su video e
poi ristampano il prompt
– stampa il messaggio
ವ LVFULYL
– stampa e aggiunge il
riferimento remoto alla
lista dei peers
– usando il nickname
passato come parametro
// continua…
49
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Alcuni commenti sulla Chat
• Applicazione peer-to-peer
– peer di “dimensione” maggiore rispetto al client della
soluzione client-server
– non soggetta a fault-locali
• in caso il registry cada, chi è connesso continua a chattare fino alla
chiusura (esempio classi di partial faults tolerance)
• Un problema:
– su un registry che si trova su un host diverso dalla JVM
• si può fare lookup() e list()
• ma non si può fare la bind(), rebind() !
– con questa implementazione si può fare una chat solo se ci si
51
trova sullo stesso host (stesso registry!)
public void abbandona (Remote idRef)
throws RemoteException {
int indice = peers.indexOf(idRef);
Object app = peers.remove(indice);
System.out.print ("\n"+
((Chat) idRef).getNickname()
+" ha abbandonato la chat"+"\n“
+PROMPT);
}
public String getNickname ()
throws RemoteException{
return nickname;
}
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
ChatImpl.java (5)
static ArrayList peers = new ArrayList();
static String nickname;
public static final String HOST=“localhost";
public static final String PROMPT="Comandi >";
}
ವ DEEDQGRQD
– cerca il riferimento da
cancellare e lo elimina
• Si può usare
idRef.getNickname()
perché il peer che esce
effettua prima le chiamate
a abbandona e poi esce
ವ JHW1LFNQDPH
• Variabili di istanza
• Costanti utili
50