140 likes | 243 Views
IN-ODP gruppe 17. sep 2002. Blandede klienter/tenare. Ein klient som besvarer kall frå andre (feks tenaren) Tilbakekall Klienten har kalla ein metode i tenaren, denne metoda ynskjer å kalle ein metode i klienten. Problemet ligg i om det er ein ledig tråd til å handtera tilbakekallet
E N D
Blandede klienter/tenare • Ein klient som besvarer kall frå andre (feks tenaren) • Tilbakekall • Klienten har kalla ein metode i tenaren, denne metoda ynskjer å kalle ein metode i klienten. • Problemet ligg i om det er ein ledig tråd til å handtera tilbakekallet • I ORBacus 4.0.2 er “threaded server” default for tenar. • I ORBacus 3 var det ikkje slik... korleis vart det då?
Klienttenar Tenar m. trådbasseng sovande aktiv blokkert Klienttenar utan “threaded server” T1 T2 T3 T Tid register() update() VRANGLÅS
Klienttenar Tenar m. trådbasseng sovande aktiv blokkert Klienttenar med “threaded server” T1 T2 T3 T1 new & start Tid T2 register() update() retur retur
IDL for vår tilbakekall module callback { /* subscriber står før supplier, fordi supplier må vite om subscriber. dette kan også gjerast ved "predefineringer" */ interface subscriber { void youseeme(in long id, in string magazine); }; interface supplier { void iseeyou(in subscriber iam); }; };
Implementasjon av tilbakekall public class subscriberImpl extends subscriberPOA { private int id; private String magazine; public void youseeme(int id, String magazine) { this.id = id; this.magazine = magazine; } public void igot() { System.out.println("ID: " + id + “ Magasin: " + magazine); } } public class supplierImpl extends supplierPOA { public void iseeyou(subscriber iam) { System.out.println("Nokon vil registrera seg..."); iam.youseeme(42, "Hitch hikers guide"); System.out.println("Registrering OK, gav ID " + 42 + ", abonnent på” + ” 'Hitch hikers guide'"); } }
Startere av tilbakekall public class supplierStarter { public static void main(String args[]) { /* corba magic */ } static int run(org.omg.CORBA.ORB orb) throws ... { /* corba magic */ supplierImpl sI = new supplierImpl(); supplier s = sI._this(orb); try { /* skriv supplierobjektreferansen til fil */ manager.activate(); orb.run(); } catch (java.io.IOException ex) { /* feilmeld */ ) return 0; } } public class subscriberStarter { public static void main(String[] args) { /* corba magic */ } static int run(org.omg.CORBA.ORB orb) throws ... { /* corba magic */ subscriberImpl subI = new subscriberImpl(); subscriber sub = subI._this(orb); manager.activate(); try { /* les frå fila og få tak i supplierobjektet (sup) */ sup.iseeyou(sub); subI.igot(); // orb.run() her?? } catch (java.io.IOException ex) { /* feilmeld */ } return 0; } }
supplierStarter subscriberStarter static main() static main() run() run() supplierImpl supplier {interface} iseeyou(subscriber) iseeyou(subscriber) subscriber {interface} subscriberImpl youseeme(ID,magazine) ID: long magazine: String youseeme(ID, magazine) Klassediagram 0 1 0..1 1 * 0
a subscriberStarter file “supplier.ref” (*) a supplierStarter a subscriberImpl a supplierImpl Sekvensdiagram (*) indicates a hardcoded file on a shared filesystem. new ref := object_to_string(supplier) new write(ref) ref := read() string_to_object(ref) iseeyou(subscriber) youseeme(ID, magazine) return return igot()
Detaljar i ORBACUS-koden • Impl-objekt må bli oppretta (med new), og bli presentert for ORB/POA (med _this()) • Ein global, unik referanse til objektet må gjerast tilgjengeleg for omverda • Ved hjelp av delte filer (dårleg løysing) • Ved hjelp av naming service • Ved hjelp av trader • POA må aktiverast (manager.activate()) • Når treng ORB å gå inn i sin event loop? (orb.run())
“Klienten” for ORBacus 3.0 public class myClientImpl extends _myClientImplBase implements Runnable { public myClientImpl(myServer s) { S = s; Thread t = new Thread(this); t.start(); } public void run() { S.register(this); } public void set_id(int id) { /* ... */ } public int get_id() { /* ... */ } private int ID; private myServer S; } Trådhandteringa kan vere interessant for obligen i ein annan samanheng!
Oblig: “fem på rad” - oversikt • Sentral spilltenar • tusler og går “evig” • lar to og to klientar spele mot kvarandre • bestemmer når spillet er vunnet og kven som vann • skal takle “vanleg bruk”, dvs også at ein spiller avslutter • Spillklientar • Grafisk brukargrensesnitt (Playerwindow?) • Kan registrere seg, avslutte spillet, motta visse meldingar frå spilltenaren • Har ikkje kontakt med motspelaren direkte, all kommunikasjon går via tenaren. • OBS: litt trådforvirring i kommentarar, identifiser desse
Oblig “fem på rad” - krav • Spillere skal ha grafisk brukergrensesnitt, men bruk av Playerwindow er ikkje påkrevd. • Dokumentasjon: UML Klassediagram og sekvensdiagram, det siste helst også for ‘rare’ situasjoner (ekvivalenter til UML kan brukast) • muligens ynskjer de å gjere noko som ikkje er UML-standard. Dette er ok, men forklar kva de har gjort. • De treng ikkje implementere motstand mot uærlige klienter eller tenarar (men de bør ikkje ukritisk køyre andre sine tenarar!), heller ikkje ta særleg høgde for at feil kan oppstå (tenar/klient-krasj). • Derimot SKAL den gitte IDL følges, den skal IKKJE utvidast, og systemet dykkar bør vere laga slik at de kan køyre mot andre tenarar/klienter. Muligens lagar kursleiinga ein test-tenar og ein test-klient. • Innleveringa SKAL kome på papir og det SKAL vere mogleg for meg å få kompilere og køyre kildekoden dykkar (dvs kildekode elektronisk). • Til sist: det kan ta uforholdsmessig lang tid å lage UML-diagramma elektronisk, det er heilt greit å levere håndteikningar så lenge dei er tydelege.
Oblig - playerWindow • Ei .jar-fil som de kan byrje å bruke utan modifikasjoner. • Anbefales, om de ikkje har masse tid til overs. • Kildekoden kan de, om de vil, hente og endre på. Men dokumenter det de gjer. • PlayerWindow er eit vindu som teikner brettet og diverse knapper, og brikkene etter kvart som dei legges ut. Eit spiller-objekt kaller visse metodar i PlayerWindow for å oppdatere vinduet, og spiller-objektet får tilbakemeldinger frå PlayerWindow (dvs brukaren) via PlayerWindowEvents. Omverda må då rette seg etter visse krav frå PlayerWindow, nemlig • Eit spiller-objekt må “implement” PlayerWindowListener. Det er tre metodar som må implementerast, “onExitGame”, “onNewGame” og “onBoardClicked”. • Spiller-objektet bruker eventuelt informasjon frå PlayerWindowEvent for å vite meir om kva som har skjedd (som kva for ei rute brukaren klikka i). • Det er IKKJE nødvendig å kunne PlayerWindow, dere treng berre kjennskap til grensesnittet!