Programmering i Java http www tisip noJavabok Distribuerte
Programmering i Java http: //www. tisip. no/Javabok/ Distribuerte systemer Hva er et distribuert system? Socketer og socket-programmering Objekter som samarbeider over nettet (RMI) RMI, litt mer i dybden Huskeliste: Å lage et enkelt distribuert system RMI og appleter Deploymentdiagram Distribuert system med tilbakekall versjon desember 2002 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. side 2 side 3 -6 side 7 -13 side 14 -16 side 17 -18 side 19 side 20 -22 side 23 -25 Kapittel 19
Hva er et distribuert system? • Et distribuert system 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. 2
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. 3
Et klientprogram sender data til et tjenerprogram over et nettverk socket 4. 340 klientprogram kjører 0. 99. 5 ve : 16 En prø 186. 45. 33. 110 data tjenerprogram kjører, inngang 35 : 35 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. 4
Å 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. 5
Kommunikasjon mellom programmene Klient Tjener åpne tjenersocket og vente (tjener. accept()) les navn på tjenermaskin fra konsoll og sett opp forbindelse til tjenerprogrammet åpne strømmer for kommunikasjon send (skriv) innledning til klienten motta (les) innledning fra tjeneren les en. Linje fra konsoll send (skriv) en. Linje til tjeneren motta (les) en. Linje fra klienten skriv en. Linje 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. 6
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 en nei-stemme Ja Nei registrer 25 nei-stemmer 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. 7
Remote Method Invocation (RMI) • • Et fjernt objekt 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: Navnet på interfacet er Ja. Nei. Teller. Interfacet må være import java. rmi. *; subinterface til interface Ja. Nei. Teller extends Remote { java. rmi. Remote. void øk. Antall. Ja() throws Remote. Exception; void øk. Antall. Nei() throws Remote. Exception; void øk. Antall. Ja(int økning) throws Remote. Exception; void øk. Antall. Nei(int økning) throws Remote. Exception; Enhver metode i int finn. Antall. Ja() throws Remote. Exception; interfacet må kunne kaste int finn. Antall. Nei() throws Remote. Exception; java. rmi. } Remote. Exception. 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. 8
Klassen er implementasjonen import java. rmi. *; import java. rmi. server. *; class Ja. Nei. Teller. Impl extends Unicast. Remote. Object implements Ja. Nei. Teller { private int antall. Ja = 0; Klassen heter private int antall. Nei = 0; Ja. Nei. Teller. Impl. public Ja. Nei. Teller. Impl() throws Remote. Exception { } public synchronized void øk. Antall. Ja() throws Remote. Exception { Klassen må være subklasse til antall. Ja++; java. rmi. server. } public synchronized void øk. Antall. Nei() throws Remote. Exception { Unicast. Remote. Object. antall. Nei++; } public synchronized void øk. Antall. Ja(int økning) throws Remote. Exception { Vi må alltid lage antall. Ja += økning; konstruktør. } public synchronized void øk. Antall. Nei(int økning) throws Remote. Exception { antall. Nei += økning; } public synchronized int finn. Antall. Ja() throws Remote. Exception { Klassen må implementere return antall. Ja; } interfacet Ja. Nei. Teller. public synchronized int finn. Antall. Nei() throws Remote. Exception { return antall. Nei; Metodene i mutable } Koden inneholder utskriftsetninger i hver } klasser bør være 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. synchronized. 9
Fjernobjekt • For at objektet skal være tilgjengelig over nettet, må det tilhøre (en subklasse til) klassen Unicast. Remote. Object. • 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. 10
Et program på tjenermaskinen må lage objektet import java. rmi. *; import java. rmi. server. *; Tråden her gjør at class Teller. Tjener { programmet går ”evig”. public static void main(String[] args) throws Exception { System. out. println("Skal lage et tjenerobjekt"); Ja. Nei. Teller tellemaskin = new Ja. Nei. Teller. Impl(); Registrerer objektet i bootstrap System. out. println("Nå er det laget!"); registreringstjenesten. Naming. rebind("AS Tellebyrå", tellemaskin); System. out. println("Nå venter vi bare på at noen skal telle oss opp. . . "); } Utskrift: Skal lage et tjenerobjekt } Nå er det laget! Nå venter vi bare på at noen skal telle oss opp. . . Nå ble antall ja-stemmer økt med 1 Nå ble antall nei-stemmer økt med 1 Nå ble antall ja-stemmer økt med 10 Nå 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. 11
Programmet på klientsiden ser slik ut: import java. rmi. *; import java. rmi. server. *; class Teller. Klient { public static void main(String[] args) throws Exception { String url = "rmi: //localhost/"; // navnet på maskinen der tjeneren kjører Ja. Nei. Teller tellemaskin = (Ja. Nei. Teller) Naming. lookup(url + "AS Tellebyrå"); tellemaskin. øk. Antall. Ja(); tellemaskin. øk. Antall. Nei(); System. out. println("Antall ja: " + tellemaskin. finn. Antall. Ja() + " Antall nei: " + tellemaskin. finn. Antall. Nei()); tellemaskin. øk. Antall. Ja(10); tellemaskin. øk. Antall. Nei(20); System. out. println("Antall ja: " + tellemaskin. finn. Antall. Ja() + " Antall nei: " + tellemaskin. finn. Antall. Nei()); 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. 12
Å kjøre programsystemet fra kommandolinjen i MS-DOS • Last ned alle java-filene fra katalogen Ja. Nei. Teller under eksempler, kapittel 19 – også filen Ja. Nei. Teller. Impl_Stub. java. • Kompiler alle filene: – javac *. java • Start registreringstjenesten i et eget vindu: – start rmiregistry • Start tjenerprogrammet i et eget vindu: – start java Teller. Tjener • Kjør klientprogrammet: – java Teller. Klient • 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. 13
Hva skjer når en klient sender en melding til et fjernobjekt? 1. Meldingen sendes til et objekt på klientsiden som fungerer som en stedfortreder (engelsk: proxy). Dette objektet er laget automatisk. 2. For denne stedfortrederen er meldingen implementert slik at følgende informasjon sendes over nettet: 1. En identifikasjon av fjernobjektet, navnet på metoden som skal kalles, samt argumentene til metoden. Her har vi forbindelsen til socketprogrammeringen. 3. På tjenersiden blir informasjonen lest, og riktig melding blir sendt til det virkelige objektet. 4. Dersom klienten skal ha en returverdi tilbake, vil tjeneren sende den til stedfortrederobjektet på klientsiden. 5. Stedfortrederen vil sende returverdien videre til den virkelige klienten. • • Stedfortrederobjektet tilhører klassen Ja. Nei. Teller. Impl_Stub. Filen Ja. Nei. Teller. Impl_Stub. java lages av Java-verktøyet rmic, slik: >rmic –v 1. 2 Ja. Nei. Teller. Impl • • Stubb-klassen kompileres automatisk. Klassen Ja. Nei. Teller. Impl_Stub implementerer interfacet Ja. Nei. Teller. 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. 14
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. 15
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. 16
Huskeliste: Å lage et enkelt distribuert system 1. Klassene kan deles i tre grupper: a) 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. b) Klasser som kun brukes som parametertype eller returtype i metodekall som sendes over nettet, må implementere java. io. Serializable. c) Øvrige klasser trenger vi ikke å gjøre noe spesielt med. 2. For klassene i gruppe 1 a) a) Lag interface og implementasjon. Husk kravene som stilles til både interface og implementasjonsklasse. Se side 8 og 9. Kompiler. b) Kjør rmic for å generere stubb-klasse, eksempel på kjøring: >rmic -v 1. 2 Ja. Nei. Teller. Impl 3. Lag tjenerprogram. La det ligge på samme katalog som interface og implementasjon. Kompiler. 4. 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. 5. Start registeret fra samme katalog som tjenerprogrammet kjører: >start rmiregistry 6. Start tjenerprogrammet. 7. 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. 17
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. 18
RMI og appleter • Klientprogrammet foran 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. 19
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. 20
Notasjon i et deploymentdiagram en node i nettverket et objekt på noden komponent ”…realiserer interfacet…” B A pilen viser avhengighet, betyr at B er avhengig av A for å eksistere 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. 21
Klient. PC kommuniserer med et rmi-register og ”AS Tellebyrå” på maskinen tjener. idb-hist. no tjener. idb. hist. no AS Tellebyrå : Teller. Tjener Ja. Nei. Teller : rmiregister : Internett : klient. PC : 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. 22
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 Teller. Tjener >start java Teller. Klient 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. 23
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. 24
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. 25
- Slides: 25