Internetprogrammering
2000
Föreläsning 10
Distribuerad programmering med Javas
RMI, Remote Method Invocation
previous
next
RMI.
Remote Method Invocation, RMI
• Distributionspaketet RMI introducerades i Java 1.1
• RMI gör det enkelt att dela på objekt mellan olika
plattformar
– objekt i en maskin kan transparent anropa objekt tillhörande
andra maskiner
– kompilerad kod kan flyttas och exekvera i olika virtuella
maskiner
• RMI kräver dock att både klient och server kör Java
previous
next
2
RMI.
Vad behöver göras för att distribuera objekt?
1 Skapa gränssnitt för objekt som skall kunna anropas av objekt på
andra maskiner.
– Detta gränssnitt (interface) används av både server och klient
– interfacet skall utvidga java.rmi.Remote
– varje metod i interfacet skall deklarera att det kastar
java.rmi.RemoteException
2 Vi behöver skapa en klient
– Som använder objektet på servern
3 Ett objekt som implementerar gränssnittet i steg 1
4 En server som skapar en instans av det distribuerade objektet
(som också implementerar samma gränssnitt som objektets
representation hos klienten)
previous
next
3
RMI.
Hur representeras objektet hos server respektive klient?
• Hos servern skapas en vanlig instans som implementerar det distribuerade
gränssnittet
• Då man (via namnservern) "ber om" en instans av det distribuerade objektet
hos klienten skickas en stubbe från servern till klienten
• Hos klienten skapas en proxy som från klientens sida ser ut som om objektet
befann sig på dess lokala maskin (dvs det ser ut som ett vanligt objekt som
implementerar det givna "distributionsgränssnittet")
• Proxyn ansvarar för att på ett transparent sätt vidarebefordra meddelanden från
klient till det riktiga objektet på servern samt att returnera resultatet tillbaks till
anroparen
– Dvs klienten skall inte kunna skilja ett meddelande till objektet på servern från ett
meddelande till ett "vanligt" lokalt objekt
previous
next
4
RMI.
Transport av seriealiserat objekt från klient till server
• Ett litet exempel som visar hur vi kan konstruera en klass och ett objekt på
klientsidan och skicka det till en server för exekvering
• Konstruktion av interface för objektet som skall implementeras på servern och
anropas av klienten
import java.rmi.*;
Objekt som
kan anropas
av annan nod
interface HelloWithTransport extends Remote {
public void sayHelloVia(HelloTransportInterface
transportObject)
throws java.rmi.RemoteException;
}
• Interface för objekt som skall kunna transporteras
Objekt som
kan flyttas
import java.io.Serializable;
interface HelloTransportInterface extends
Serializable{
public void say(String saying);
}
previous
next
5
RMI.
Konstruktion av Server...
import java.rmi.*;
import java.rmi.server.*;
Subklassa
UnicastRemoteObject
och implementera det egna
HelloWithTransport
public class HelloServerTransport extends UnicastRemoteObject
implements HelloWithTransport {
public HelloServerTransport() throws RemoteException {
super();
Superklassens
}
konstruktör
och metoden som definieras
ser till att
i HelloWithTransport
"vår"
som sen kommer användas
instans
av klienter
exporteras
public void sayHelloVia(HelloTransportInterface
transportObject) throws RemoteException {
transportObject.say("Hello Internetprogrammers (via
transport)!");
}
previous
next
6
RMI.
...
public static void main(String [] args) {
if (System.getSecurityManager() == null)
System.setSecurityManager(new RMISecurityManager());
try {
HelloServerTransport h = new HelloServerTransport();
Skapa instans
Naming.rebind(”//host/hellowithtransport", h);
Ge "distribuerat" namn
System.out.println("Hello with Callback Server
ready.");
}
catch(RemoteException re) {
System.out.println("RemoteException in
HelloServerTransport.main: " + re);
}
catch(Exception e) {
System.out.println("Exception in
HelloServerTransport.main: " + e);
}}}
previous
next
7
RMI.
Klient
import java.rmi.*;
import java.io.*;
public class HelloClientWithTransport {
public static class MyTransportObject implements
HelloTransportInterface {
public void say(String saying){
System.out.println("From the client: " + saying);
}
}
public static void main(String [] args) {
System.out.println("Client started");
if (System.getSecurityManager() == null)
System.setSecurityManager(new RMISecurityManager());
try {
HelloWithTransport
h = (HelloWithTransport)
Skapa
Naming.lookup(”//host/hellowithtransport");
referens till
servern
previous
next
8
RMI.
...
//Transportera koden för ett objekt och exekvera hos servern.
MyTransportObject
transport = new MyTransportObject ();
Skapa instans
(av klienten)
h.sayHelloVia(transport);
}
Anropa metod
hos servern
med klienten som
argument
catch(Exception e) {
System.out.println("Exception in
HelloClientWithTransport .main: " + e);
}
}}
previous
next
9
RMI.
Kompilera
• Kompilera båda interfacen, servern och klienten med javac,
dvs
>javac HelloWithTransport.java
>javac HelloTransportInterface.java
>javac HelloServerTransport.java
>javac HelloClientWithTransport.java
• Kör också rmic på servern, dvs
>rmic HelloServerTransport
previous
next
10
RMI.
Testkörning
Vi kör exemplet på följande sätt (svar i kursivt):
• Starta namnserver
>rmiregistry
• Starta server
>java HelloServerTransport
Hello with Callback Server ready.
• Starta klient
>java HelloClientWithTransport
Client started
Iockmed att klienten startas kommer också
följande skrivas på severns terminal:
From the client: Hello Internetprogrammers
(via transport)!
previous
next
11
RMI.
Definiera, kompilera och kör
• Kortfattat gör på följande sätt
– Skapa interface
– Kompilera interfacet med javac InterfaceNamn.java
– Skapa server som instansierar serverobjekt och binder det till namnservern
– Kompilera servern med javac ServerKlass.java
– Kör rmic på serverklassen (så skapas stubbe och skelettklasser), dvs
rmic ServerKlass
– Skriv klient som refererar objekt i namnservern och skickar meddelanden
till det
– Kompilera klienten (javac KlientKlass.java)
– Starta namnservern (rmiregistry)
– Starta server (java ServerKlass)
– Starta klint (Java KlientKlass)
previous
next
12
RMI.
RMI mer beskrivningar och fler exempel
Vi tittar också på tutorialen på följande adress:
http://www.javasoft.com/docs/books/tutorial/rmi/index.html
Vi tittar också på dom tre exemplen på följande sida
http://www.nada.kth.se/kurser/kth/2D4334/00-01/contents/exempel.html
dvs följande:
• Transport av serialiserat objekt
• Calbackrutin
• Meddelandesystem
previous
next
13