E N D
Distribuerte systemer Hva er et distribuert system? side 2Socketer og socket-programmering side 3-6Objekter som samarbeider over nettet (RMI) side 7-13RMI, litt mer i dybden side 14-16Huskeliste: Å lage et enkelt distribuert system side 17-18RMI og appleter side 19Deploymentdiagram side 20-22Distribuert system med tilbakekall side 23-25 Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Hva er et distribuert system? • Et distribuertsystem består av flere programmer som kjører på flere datamaskiner, og som kommuniserer med hverandre. • En klient er et program eller en datamaskin som ber om tjenester fra en tjener, oftest over et nettverk. • En tjener er et program eller en datamaskin som utfører oppgaver på forespørsel fra klienter. • Klient og tjener er roller som programmer og maskiner spiller. • Eksempel: En maskin blir en klient dersom vi kjører et klientprogram på den. • En og samme maskin kan spille begge rollene. • Et og samme program kan også spille begge rollene, det mottar forespørsler fra andre, og det stiller selv spørsmål til andre programmer. Jamfør samarbeid mellom objekter. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Socketer • Datamaskiner kommuniserer med hverandre ved at data sendes fra én maskin til en annen over et nettverk. • En protokoll er et sett regler som sier hvordan denne datastrømmen skal sendes fra avsender og tolkes hos mottaker. Eksempel: • Internett-protokollen (IP) beskriver hvordan datamaskiner skal kommunisere med hverandre over Internett. • For at maskiner skal kunne kommunisere med hverandre må de være identifiserbare. Datamaskiner knyttet til Internett identifiseres ved hjelp av en IP-adresse, eksempler: 186.45.34.100 og 156.76.50.237. • For at vi skal slippe å forholde oss til disse tallene, har en maskin vanligvis også et navn. Eksempler på navn er java.sun.com og tonje.idb.hist.no. • Dersom vi bruker navnet, vil nettverksprogramvaren i datamaskinen slå opp den tilsvarende IP-adressen i Internett sin navnetjeneste. En database over sammenhengen mellom navn og IP-adresser er distribuert i Internett, og de enkelte maskinene vet hvor de skal henvende seg for slike oppslag. • En socket består av IP-adresse (eller maskinnavn) og portnummer, vanligvis atskilt med kolon, eksempel tonje.idb.hist.no:100. • Portnummeret bruker vi til å identifisere et bestemt tjenerprogram som kjører på maskinen. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Et klientprogram sender data til et tjenerprogram over et nettverk data 186.45.33.110 En prøve :160.99.54.340 :35 tjenerprogram kjører, inngang 35 socket klientprogram kjører Internett 160.99.54.340 Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Å programmere kommunikasjonen mellom programmer • Forbindelsen mellom klient- og tjenerprogram opprettes ved å lage et objekt av klassen java.net.Socket. • Vi knytter strømmer til Socket-objektet. • Et program som skal sende data, skriver til strømmen. • Et program som skal motta data, leser fra strømmen. • Akkurat som ved filbehandling… • Klient- og tjenerprogrammer kan i en utprøvingsfase gjerne kjøre i hver sin Java-tolker på samme maskin. Maskinen må i praksis ha nettverkskort installert, da programvaren knyttet til dette også brukes når begge programmene kjører på samme maskin. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Tjener Kommunikasjon mellom programmene åpne tjenersocket og vente (tjener.accept()) Klient les navn på tjenermaskin fra konsoll og sett opp forbindelse til tjenerprogrammet åpne strømmer for kommunikasjon åpne strømmer for kommunikasjon send (skriv) innledning til klienten motta (les) innledning fra tjeneren les enLinje fra konsoll send (skriv) enLinje til tjeneren motta (les) enLinje fra klienten skriv enLinje til konsoll send (skriv) svar til klienten motta (les) respons fra tjeneren Vis programliste 19.1 side 613-615 Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Objekter som samarbeider over nettet • Repetisjon fra kapittel 3: • Klient og tjener er roller som objekter spiller. • Objekter samarbeider ved at et klientobjekt etterspør en tjeneste ved å sende en melding til et tjenerobjekt. • Tjeneren utfører en operasjon som reaksjon på meldingen. • Tjeneren kan sende svar tilbake til klienten. • Objektene som samarbeider kan ligge på forskjellige maskiner. figur side 112 registrer en ja-stemme registrer 25 nei-stemmer Ja Nei registrer en nei-stemme registrer 32 ja-stemmer Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Remote Method Invocation (RMI) • Et fjerntobjekt er et objekt som kjører i en Java-tolker på en annen maskin, eller i en annen Java-tolker på samme maskin. • Socketprogrammering ligger i bunnen, men vi forholder oss til objekter og meldinger slik vi er vant med. • Klienten må kjenne grensesnittet til objektet den skal sende meldinger til. • Grensesnittet til fjernobjekter må spesifiseres i et interface: import java.rmi.*; interface JaNeiTeller extends Remote { void økAntallJa() throws RemoteException; void økAntallNei() throws RemoteException; void økAntallJa(int økning) throws RemoteException; void økAntallNei(int økning) throws RemoteException; int finnAntallJa() throws RemoteException; int finnAntallNei() throws RemoteException; } Navnet på interfacet er JaNeiTeller. Interfacet må være subinterface til java.rmi.Remote. Enhver metode i interfacet må kunne kaste java.rmi. RemoteException. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Klassen er implementasjonen import java.rmi.*; import java.rmi.server.*; class JaNeiTellerImpl extends UnicastRemoteObject implements JaNeiTeller { private int antallJa = 0; private int antallNei = 0; public JaNeiTellerImpl() throws RemoteException { } public synchronized void økAntallJa() throws RemoteException { antallJa++; } public synchronized void økAntallNei() throws RemoteException { antallNei++; } public synchronized void økAntallJa(int økning) throws RemoteException { antallJa += økning; } public synchronized void økAntallNei(int økning) throws RemoteException { antallNei += økning; } public synchronized int finnAntallJa() throws RemoteException { return antallJa; } public synchronized int finnAntallNei() throws RemoteException { return antallNei; } } Klassen heter JaNeiTellerImpl. Klassen må være subklasse til java.rmi.server. UnicastRemoteObject. Vi må alltid lage konstruktør. Klassen må implementere interfacet JaNeiTeller. Metodene i mutable klasser bør være synchronized. Koden inneholder utskriftsetninger i hver metode. Utelatt her av plasshensyn. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Fjernobjekt • For at objektet skal være tilgjengelig over nettet, må det tilhøre (en subklasse til) klassen UnicastRemoteObject. • Et objekt av en slik klasse medfører at det startes en egen tråd som holder objektet i live i det uendelige (eller inntil programmet som objektet tilhører avbrytes). • Dette objektet er tjeneren som venter på forespørsler fra klienter. • Interfacet spesifiserer grensesnittet, mens klassen beskriver implementasjonen av et slikt objekt. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Et program på tjenermaskinen må lage objektet import java.rmi.*; import java.rmi.server.*; class TellerTjener { public static void main(String[] args) throws Exception { System.out.println("Skal lage et tjenerobjekt"); JaNeiTeller tellemaskin = new JaNeiTellerImpl(); System.out.println("Nå er det laget!"); Naming.rebind("AS Tellebyrå", tellemaskin); System.out.println("Nå venter vi bare på at noen skal telle oss opp..."); } } Tråden her gjør at programmet går ”evig”. Registrerer objektet i bootstrap registreringstjenesten. Utskrift:Skal lage et tjenerobjektNå er det laget!Nå venter vi bare på at noen skal telle oss opp...Nå ble antall ja-stemmer økt med 1Nå ble antall nei-stemmer økt med 1Nå ble antall ja-stemmer økt med 10Nå ble antall nei-stemmer økt med 20 Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Programmet på klientsiden ser slik ut: import java.rmi.*; import java.rmi.server.*; class TellerKlient { public static void main(String[] args) throws Exception { String url = "rmi://localhost/"; // navnet på maskinen der tjeneren kjører JaNeiTeller tellemaskin = (JaNeiTeller) Naming.lookup(url + "AS Tellebyrå"); tellemaskin.økAntallJa(); tellemaskin.økAntallNei(); System.out.println("Antall ja: " + tellemaskin.finnAntallJa() + " Antall nei: " + tellemaskin.finnAntallNei()); tellemaskin.økAntallJa(10); tellemaskin.økAntallNei(20); System.out.println("Antall ja: " + tellemaskin.finnAntallJa() + " Antall nei: " + tellemaskin.finnAntallNei()); } } Utskrift: Antall ja: 1 Antall nei: 1 Antall ja: 11 Antall nei: 21 Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Å kjøre programsystemet fra kommandolinjen i MS-DOS • Last ned alle java-filene fra katalogen JaNeiTeller under eksempler, kapittel 19 – også filen JaNeiTellerImpl_Stub.java. • Kompiler alle filene: • javac *.java • Start registreringstjenesten i et eget vindu: • start rmiregistry • Start tjenerprogrammet i et eget vindu: • start java TellerTjener • Kjør klientprogrammet: • java TellerKlient • Rmi-registeret og tjenerprogrammet må stoppes med Ctrl+C. Gjør oppgavene side 622 Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Hva skjer når en klient sender en melding til et fjernobjekt? • Meldingen sendes til et objekt på klientsiden som fungerer som en stedfortreder (engelsk: proxy). Dette objektet er laget automatisk. • For denne stedfortrederen er meldingen implementert slik at følgende informasjon sendes over nettet: • En identifikasjon av fjernobjektet, navnet på metoden som skal kalles, samt argumentene til metoden. Her har vi forbindelsen til socketprogrammeringen. • På tjenersiden blir informasjonen lest, og riktig melding blir sendt til det virkelige objektet. • Dersom klienten skal ha en returverdi tilbake, vil tjeneren sende den til stedfortrederobjektet på klientsiden. • Stedfortrederen vil sende returverdien videre til den virkelige klienten. • Stedfortrederobjektet tilhører klassen JaNeiTellerImpl_Stub. • Filen JaNeiTellerImpl_Stub.java lages av Java-verktøyet rmic, slik: >rmic –v1.2 JaNeiTellerImpl • Stubb-klassen kompileres automatisk. • Klassen JaNeiTellerImpl_Stub implementerer interfacet JaNeiTeller. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Overføring av argumenter • Hittil har klient og tjener kjørt i samme Java-tolker: • Verdiene til argumentene overføres ved metodekall: • Datatypen er en primitiv datatype: Metoden jobber med en kopi av argumentet. • Datatypen er en referansetype: Metoden får en kopi av referansen, men ikke av objektet selv. Metoden kan derfor endre på dette objektet, som gjerne hører hjemme hos klienten. • Tilsvarende returneres verdier ved retur fra en ikke-void metode. • I et RMI-system vil argumentene kunne overføres fra én Java-tolker til en annen: • Hvis et fjernobjekt skal overføres, blir et stedfortrederobjekt overført. • Mottakeren kan sende meldinger til det egentlige objektet via stedfortrederen. • Objekter som tilhører en “ikke-fjern klasse” overføres ved serialisering. • En klient som mottar et slikt objekt, mottar altså en kopi av objektet på tjenersiden. • Klienten kan endre objektet uten at dette berører objektet på tjenersiden. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Når trenger vi fjernobjekter, og når skal vi bruke serialiserbare objekter? • Vi må lage fjernobjekter dersom vi ønsker at en klient skal kunne sende meldinger til objektet over nettet (fra én Java-tolker til en annen). Alle klientene (og tjeneren) forholder seg til det samme objektet. • Vi bruker serialiserbare objekter dersom de ulike Java-tolkerne kan jobbe med hver sin kopi av objektet. Vis klassen Person fra programliste 15.5 side 496-501 og programliste 19.4 side 624-627. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Huskeliste: Å lage et enkelt distribuert system • Klassene kan deles i tre grupper: • Finn ut hvilke objekter det er ønskelig at en klient skal kunne sende meldinger til over nettet. Klassene som disse objektene tilhører må spesialbehandles som forklart under punkt 2. • Klasser som kun brukes som parametertype eller returtype i metodekall som sendes over nettet, må implementere java.io.Serializable. • Øvrige klasser trenger vi ikke å gjøre noe spesielt med. • For klassene i gruppe 1a) • Lag interface og implementasjon. Husk kravene som stilles til både interface og implementasjonsklasse. Se side 8 og 9. Kompiler. • Kjør rmic for å generere stubb-klasse, eksempel på kjøring: >rmic -v1.2 JaNeiTellerImpl • Lag tjenerprogram. La det ligge på samme katalog som interface og implementasjon. Kompiler. • Lag et eller flere klientprogram. Et klientprogram trenger kompilert interface og kompilert stubb-klasse. Det enkleste er å la dette ligge på samme katalog som klientprogrammet. Kompiler klientprogrammet. • Start registeret fra samme katalog som tjenerprogrammet kjører: >start rmiregistry • Start tjenerprogrammet. • Kjør eventuelle klientprogram. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Tips ved programutvikling • Legg inn mange utskriftsetninger både på tjener- og klientside for å logge aktiviteten. • Start registeret på nytt for hver gang tjenerprogrammet må startes på nytt. • Husk å kjøre rmic på nytt dersom interfacet forandres. Gjør oppgavene side 628 Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
RMI og appleter • Klientprogrammet foran kan kjøres fra en hvilken som helst maskin som er koblet til Internett, forutsatt at kompilert interface og kompilert stubb-klasse er tilgjengelig. • Hva med en applet som klient? • Klassene blir nå distribuert via den html-siden som inneholder en referanse til appleten. • Ved kjøring vil kompilert interface og kompilert stubb-klasse etterspørres av appleten. Disse blir automatisk hentet fra samme sted som appleten. • Men – • En applet har kun tilgang til ressurser på den maskinen den ble lastet ned fra. • Rmi-registeret og tjenerobjektene må derfor kjøre på denne maskinen. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Deploymentdiagram og UML-komponenter • Et distribuert system består av flere deler som kjører på forskjellige maskiner. • De forskjellige delene må startes opp i en bestemt rekkefølge. • Denne sammenhengen kan illustreres i et UML-deploymentdiagram. • En UML-komponent er definert som følger: • ”A physical, replaceable part of a system that packages implementation and conforms to and provides the realization of a set of interfaces.” • En komponent karakteriseres på følgende måte: • En komponent er på mange måter “større” enn et objekt. Den består gjerne av flere objekter. • En komponent er bortimot uavhengig av andre komponenter. Den er en fysisk enhet som sammen med andre komponenter utgjør et større system. • En komponent fungerer aldri helt alene. Den må brukes innenfor en bestemt arkitektur eller teknologi. • En komponent kan byttes ut med en annen komponent som støtter de samme interfacene. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Notasjon i et deploymentdiagram en node i nettverket et objekt på noden komponent ”…realiserer interfacet…” pilen viser avhengighet, betyr at B er avhengig av A for å eksistere B A Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
KlientPC kommuniserer med et rmi-register og ”AS Tellebyrå” på maskinen tjener.idb-hist.no tjener.idb.hist.no :TellerTjener AS Tellebyrå :rmiregister JaNeiTeller :Internett :klientPC :applikasjon Gjør oppgaven side 631. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Et distribuert system med tilbakekall • Hver gang antall ja- eller nei-stemmer blir økt skal alle påloggede klienter varsles. • Tjeneren må holde oversikt over alle påloggede klienter. • Tjeneren må sende melding til klientene (rollene byttes om!). – ”tilbakekall”. • Vi må ha fjernobjekter på begge sider. • Vi starter tjenerprogrammet og to klienter: >start rmiregistry >start java TellerTjener >start java TellerKlient >start java TellerKlient Brukergrensesnitt for klient som logger seg på: Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Brukergrensesnitt, tjener og to klienter Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.
Vis programlistene 19.5, 19.6, 19.7 og 19.8 fra side 633 og utover. Gjør oppgavene side 642. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, Stiftelsen TISIP og Gyldendal Akademisk 2003.