120 likes | 285 Views
Om du har boken av Marty Hall, läs avsnitt 15.8 För fler exempel se: http://www.nada.kth.se/kurser/kth/2D4334/99-00/contents/exempel.html (exemplen kommer kanske flyttas till PMI-kursens katalog. I så fall skickas meddelande ut om detta.). RMI, Remote Method Invocation.
E N D
Om du har boken av Marty Hall, läs avsnitt 15.8 För fler exempel se: http://www.nada.kth.se/kurser/kth/2D4334/99-00/contents/exempel.html (exemplen kommer kanske flyttas till PMI-kursens katalog. I så fall skickas meddelande ut om detta.) RMI, Remote Method Invocation Distribuerad programmering med RMI Föreläsning 9 • Läs också gärna tutorialen som du hittar på följande adress: • http://www.javasoft.com/docs/books/tutorial/rmi/index.html
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
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)
Hur representeras objektet hos server respektive instans? • 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
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.*; interface HelloWithTransport extends Remote {public void sayHelloVia(HelloTransportInterface transportObject)throws java.rmi.RemoteException; } • Interface för objekt som skall kunna transporteras import java.io.Serializable; interface HelloTransportInterfaceextends Serializable{public void say(String saying); } Objekt som kan anropas av annan nod Objekt som kan flyttas
Konstruktion av Server... Subklassa UnicastRemoteObject och implementera det egna HelloWithTransport import java.rmi.*; import java.rmi.server.*; public class HelloServerTransport extends UnicastRemoteObjectimplements HelloWithTransport { public HelloServerTransport() throws RemoteException { super(); } public void sayHelloVia(HelloTransportInterface transportObject) throws RemoteException { transportObject.say("Hello Internetprogrammers (via transport)!"); } Superklassens konstruktör ser till att "vår" instans exporteras och metoden som definieras i HelloWithTransport och som kommer användas av klienter
... public static void main(String [] args) { // System.setSecurityManager(new RMISecurityManager()); try { HelloServerTransport h = new HelloServerTransport(); Naming.rebind("hellowithtransport", h); 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); } }} Skapa instans Ge "distribuerat" namn
Klient import java.rmi.*; import java.io.*; public class HelloClientWithTransport { public static class MyTransportObjectimplements HelloTransportInterface { public void say(String saying){ System.out.println("From the client: " + saying); } } public static void main(String [] args) { System.out.println("Client started"); // System.setSecurityManager(new RMISecurityManager()); try { HelloWithTransport h = (HelloWithTransport) Naming.lookup("hellowithtransport"); Skapa referens till servern
... //Transportera koden för ett objekt och exekvera hos servern.MyTransportObject transport = new MyTransportObject (); h.sayHelloVia(transport); } catch(Exception e) { System.out.println("Exception in HelloClientWithTransport .main: " + e); } }} Skapa instans (av klienten) Anropa metod hos servern med klienten som argument
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
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 startedIockmed att klienten startas kommer också följande skrivas på severns terminal: From the client: Hello Internetprogrammers (via transport)!
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)