Dopo aver visto l'uso dell'RMI, adesso è giunto il momento di complicarci un pò la vita ed introdurre il meccanismo della callback. Se un client fa una nuova offerta, gli atri client non saranno a conoscenza di questo fatto e non potranno rilanciare. Per implementare questa funzione il server dovrà disporre di un sistema per notificare a tutti client che il prezzo è cambiato. Per questo motivo i client esporranno un metodo richiamabile da remoto dal server quando il prezzo dell'oggetto cambia, in questo caso, il server agirà da client mentre i client agiranno da server. Affinchè il server sappia quali client avvisare, quest'ultimi durante la fase di connessione dovranno registrarsi sul server richiamando esplicitamente un metodo registerForNotify(). Alla chiamata di questo metodo il server conserverà da qualche parte (possibilmente un vettore) il riferimento al client in modo da avvisarlo nel caso di una nuova offerta. Supponendo di usare un vettore per memorizzare i riferimenti ai client che si sono registrati per le notifiche, al cambio del prezzo dell'oggetto il server ciclerà questo vettore e richiamerà da remoto su ogni client il metodo che espongono tramite l'interfaccia. Continuando dal codice visto in precedenza, vedremo come modificarlo in modo da inserire la callback. Partiamo quindi dall'interfaccia del server. Al file AuctionInterface.java, aggiungiamo il metodo:
che verrà richiamato dai client quando vorranno ricevere delle notifiche dal server. L'oggetto di tipo Notifiable, si riferisce all'interfaccia del client: sarà esso stesso a registrarsi sul server tramite la propria interfaccia. Continuiamo con l'implementazione del server, modifichiamo il file Auctioneer.java: La prima cosa da fare è di aggiungere un vettore in cui memorizzare i riferimenti ai client, aggiungiamo quindi all'inizio della classe (dopo 'private String product;'):
Il vettore deve anche essere istanziato, nel costruttore (public Auctioneer()) aggiungiamo dopo la riga super();
Aggiungiamo poi il metodo per far registrare i client:
Faremo si, che il client esponga tramite la propria interfaccia (Notifiable) un metodo notify che verrà chiamato da remoto dal server per notificare un evento (una nuova offerta). Richiameremo il metodo remoto notify, quando verrà proposta ed accettata una nuova offerta, cioè all'interno del metodo setBid(). Aggiungiamo quindi all'internopublic class Auction di questo metodo (dopo la riga System.out.println("Offerta Accettata...");) il seguente codice:
Si sottolinea il fatto che al client si notifica l'evento e non il nuovo prezzo. Sarà, quindi, compito del client leggere il nuovo prezzo alla chiamata del metodo notify(). Passiamo quindi al client. Per prima cosa scrivere la sua interfaccia Notifiable. Creiamo un nuovo file Notifiable.java e scriviamo:
Passiamo quindi all'implentazione del client. Modifichiamo il file Auction.java come segue: La classe Auction implementa l'interfaccia Notifiable, quindi modifichiamo la riga public class Auction come segue
Aggiungiamo al costruttore (public Auction()) il seguente codice:
Questo codice serve ad esportare il/i metodi remoti del client sul registry, visto che si è già instaurata una connessione con il server. In questo modo il client non dovrà registrare esplicitamente i propri metodi remoti sul registry. Inseriamo il codice per registrarci sul server nel main, dopo la riga auc.auctioneer = (AuctionInterface) Naming.lookup(serverName); //cerco il server sul registry :
Per finire aggiungiamo il metodo notify:
Per compilare ed eseguire il nuovo esempio dobbiamo procedere come segue(da un terminale):
Note:
Per scaricare l'esempio completo cliccare qui |