^  Help Taison

Donazione Libera Paypal

Tutorial RMI - Asta multiclient - Parte 1
Pubblicato Sabato 01 Dicembre 2007 - 14:11 (letto 25797 volte)
Programmazione.png

Tags: java  rmi  

Lo scopo di questo tutorial è quello di creare un'asta con un server ed un certo numero di client. Il server si occuperà di gestire l'asta mentre i client rappresenteranno i partecipanti all'asta.
Il server espone un certo numero di metodi che verranno invocati dai client per fare le offerte. I metodi esposti verranno usati da remoto dai client tramite il meccanismo della Remote Method Invocation.

Ovviamente questo meccanismo consente ai partecipanti all'asta di fare solo le offerte: se volessimo essere tenuti aggiornati del prezzo corrente occorrebbe interrogare di continuo il server richiamando da remoto un metodo (ad esempio getCurrendBid()). Ovviamente questo genere di chiamata è molto dispendiosa sia dal punto di vista computazionale che dalle risorse di rete sprecate poichè facciamo una chiamata ad un metodo remoto.
La soluzione a quest'ultimo problema è di usare il meccanismo della callback. Ogni client infatti una volta collegatosi ad un server remoto, può eseguire una registrazione presso il server per ricevere le notifiche su un determinato evento. Il server a sua volta, al verificarsi dell'evento, invocherà un certo metodo remoto (che il client espone) in modo da notificare ai sottoscriventi che un certo evento si è verificato. Questa tecnica che può essere vista come una sorta di RMI mutuo permette al server di comunicare degli eventi con una sola chiamata ad un metodo.
Come detto in precedenza il tutorial si divide in due parti: nella prima si farà uso di RMI e nella seconda si introdurrà il meccanismo della callback.


Il server sarà il componente che espone dei metodi remoti che saranno richiamabili dai client. Il primo passo consiste quindi nel definire un'interfaccia in cui elencheremo i metodi esposti.
Creiamo quindi un file AuctionInterface.java


import java.rmi.Remote;
import java.rmi.*;

public interface AuctionInterface extends Remote { //se usiamo RMI dobbiamo estendere l'oggetto Remote
//tutti i metodi remoti devono 'lanciare' l'eccezione RemoteException
public void setBid(int bid) throws RemoteException; //offerta
public int getCurrentBid() throws RemoteException; //ottengo il prezzo
public String getProduct() throws RemoteException; //ottengo il nome del prodotto
}


Successivamente, occorre scrivere l'implementazione di tale interfaccia.
Creiamo quindi un file Auctioneer.java.

import java.rmi.*;
import java.rmi.server.*;
import java.net.*;
import java.util.*;
import java.io.*;



public class Auctioneer extends UnicastRemoteObject implements AuctionInterface
{
private int currentBid; //variabile che contiene il prezzo corrente
private String product; //variabile che contiene il nome del prodotto corrente

public Auctioneer(String p, int b) throws RemoteException
{
super();
currentBid = b; //imposto il prezzo...
product = p; //...ed il nome
}

public int getCurrentBid() throws RemoteException { //per recuperare il prezzo corrente
System.out.println("Richiesta prezzo ...");
return currentBid;
}

public String getProduct() throws RemoteException { //per ricavare il nome del prodotto
System.out.println("Richiesta nome Prodotto ...");
return product;
}

public void setBid(int b) throws RemoteException { //per fare un'offerta'
System.out.println("Nuova Offerta ...");
if (b > currentBid) {
currentBid = b;
System.out.println("Offerta Accettata...");
}
else System.out.println("Offerta Rifiutata...");
}

public static void main(String [] args) { //da riga di comando passo NomeProdotto e PrezzoIniziale
if(args.length == 0) {
System.out.println("USAGE: java ");
System.exit(0);
}
String name = null;
try {
//questo sarà l'indirizzo del mio server
name = "rmi://" + InetAddress.getLocalHost().getHostName() + "/BidServer";
System.out.println("Nome RMI: " + name);
} catch (Exception ue) {}

Auctioneer thisOne=null;

try {
thisOne = new Auctioneer(args[0], Integer.parseInt(args[1]));
//creo un nuovo server 'thisOne' che associo all'indirizzo 'name' sull'RMI Registry'
Naming.rebind(name, thisOne);
}
catch (Exception e) {
e.printStackTrace();
}

}

}


Successivamente definiamo il comportamento del Client. Il codice è molto semplice in quanto il client deve semplicemente leggere da tastiera un numero e richiamare i metodi remoti del server per reperire prezzo corrente e nome prodotto ed eventualmente fare la nuova offerta.
Creiamo quindi un file Auction.java.


import java.io.*;
import java.rmi.*;
import java.rmi.server.*;

public class Auction
{
private int currentBid=0; //prezzo corrente
private String product=""; //nome prodotto

AuctionInterface auctioneer;

public Auction() {
}

public static void main(String [] args) {
if(args.length == 0) { //da riga di comando passo l'indirizzo del server
System.out.println("USAGE: java Auction ");
System.exit(0);
}
String serverName = "//" + args[0] + "/BidServer"; //indirizzo del Server
Auction auc = new Auction();
try {
auc.auctioneer = (AuctionInterface) Naming.lookup(serverName); //cerco il server sul registry
auc.currentBid = auc.auctioneer.getCurrentBid(); //chiamo il suo metodo remoto per conoscere il prezzo corrente
auc.product = auc.auctioneer.getProduct(); //...ed il nome dell'oggetto in vendita
System.out.println("Current Price for " + auc.product + " : " + auc.auctioneer.getCurrentBid());
}
catch (NotBoundException ex) {
System.out.println("The server is not available");
ex.printStackTrace();
}
catch(Exception e) {
e.printStackTrace();
}

boolean flag=true; //flag che servirà ad uscirà dal while

BufferedReader myInput = new BufferedReader (new InputStreamReader (System.in));
String str = new String(); //input da tastiera...
int myBid = 0;
while (flag) {
try {
System.out.print("New Bid: ");
str = myInput.readLine(); //leggo da tastiera la nuova offerta
} catch (IOException e) {
System.out.println ("Error: " + e);
}
try {
if (str=="") flag=false; //se la stringa è vuota esco impostando flag a false...
else {
myBid = Integer.parseInt(str); //ricavo l'intero dall'input
auc.currentBid = auc.auctioneer.getCurrentBid(); //aggiorno il prezzo
if (myBid>auc.currentBid) auc.auctioneer.setBid(myBid); //se la mia offerta è maggiore di quella corrente la propongo
else System.out.println("Propose Higher Bid"); //altrimenti ti dico che è troppo bassa :)
}
auc.currentBid = auc.auctioneer.getCurrentBid(); //aggiorno di nuovo e comunque il prezzo
} catch (RemoteException ex) {
ex.printStackTrace();
}
System.out.println("Current Bid is : " + auc.currentBid); //e ti dico a quanto è arrivata l'offerta
//cioè conosco il prezzo dell'oggetto solo dopo aver fatto un'offerta...
}
}
}


Per compilare ed eseguire questo esempio dobbiamo procedere come segue(da un terminale):

  • compilare il server: javac Auctioneer.java
  • compilare il client: javac Auction.java
  • eseguire il registry: rmiregistry
  • eseguire il server: java Auctioneer nome_prodotto prezzo_iniziale
  • eseguire il/i client (sullo stesso computer): java Auction localhost


Note:
  • dalla versione 1.5.0_06 della Jre non è necessario usare rmic per creare Stub e Skeleton del server.
  • nel caso in cui dovessimo avere errori del tipo (ClassNotFoundException) si può specificare il classpath. Basta aggiungere alla fine delle righe 1, 2, 4 e 5 questo -classpath ./ (per Linux) , -classpath .\ (per Windows)
  • per il deployement dell'applicazione ricordo che per il server avremo bisogno dei file Auctioneer.class ed AuctionInterface.class, mentre per il client avremo bisogno di Auction.class e AuctionInterface.class.


Trovate il codice completo cliccando qui]
Pubblicato Sabato 01 Dicembre 2007 - 14:11 (letto 25797 volte)
Print Stampa



Le ultime notizie relative a questo argomento

Read Software Gestione Buoni Postali: GBP - versione 0.2 alpha (13/02/2011 - 20:02) letto 42099 volte
Read Software Gestione Buoni Postali: GBP (08/02/2011 - 22:30) letto 42213 volte
Read JCalendar, un selettore di data per Java (28/11/2010 - 21:18) letto 26547 volte
Read Migliorare l'usabilità delle applicazioni Java con i BalloonTip (27/11/2010 - 13:30) letto 21463 volte
Read Un'utile funzione PHP per elencare i file di una cartella (26/03/2009 - 01:20) letto 19536 volte
Read Tutorial RMI - Asta multiclient con CallBack - Parte 2 (01/12/2007 - 14:19) letto 23465 volte
Read Tutorial RMI - Asta multiclient - Parte 1 (01/12/2007 - 14:11) letto 25797 volte
Read Slideshow di immagini in Flatnuke usando AHAH (24/09/2007 - 23:45) letto 23899 volte
Read FLATNUKE: Creare un archivio di immagini presenti in una cartella della galleria (17/08/2007 - 17:20) letto 23053 volte
Read Media Player su flatnuke o sul nostro sito web pt.1 (16/08/2007 - 19:49) letto 26852 volte

Tutte le notizie relative a questo argomento
Programmazione.png
Follow cesareino on Twitter
 
^  Twitter
 
^  Login





Lingua del sito:
deutsch english español français italiano português
 
^  Ads
Freely inspired to Mollio and DKBlog template