[MW] Aufgabe 8 (Jxta)


Also im Endeffekt erstellst du auf der Serverseite das Advertisement und veröffentlichst das dann im Jxta-Netzwerk:

ModuleSpecAdvertisement msadv = (ModuleSpecAdvertisement)
AdvertisementFactory.newAdvertisement(ModuleSpecAdvertisement.getAdvertisementType());
ModuleClassID myID = IDFactory.newModuleClassID();
msadv.setName("LibraryService");
msadv.setVersion("Version 1.0");
msadv.setCreator("siwerauchimmer");
msadv.setModuleSpecID(IDFactory.newModuleSpecID(myID));
msadv.setSpecURI("http://www4.informatik.uni-erlangen.de//Lehre/WS05/V_MW/Uebung/aufgaben/a8.pdf");
discovery.publish(msadv);
discovery.remotePublish(msadv);

Der obige Code ist für das ModuleSpecAdvertisement (man muss hier noch zusätzlich das PipeAdvertisement hinzufügen. Aber um erstmal Advertisements zu veröffentlichen und zu suchen reichts das so hier.)

Um nun auf Clientseite asynchron zu suchen gibt es folgenden Aufruf:

        discovery.getRemoteAdvertisements(
            null,
            DiscoveryService.ADV,
            "Name",
            "LibraryService",
            100,
            null);

Jetzt brauchst du nur noch ne Klasse, die das DiscoveryListener Interface implementiert. Dort kannst du dir dann die Advertisements mal ausgeben lassen (z.B. nach Creator abfragen usw), so daß du dann siehst, ob du dein Advertisement gefunden hast.


Ja schön, das hab ich nun ja auch soweit, aber der Client findet einfach den Server nicht.

Kann ich das vielleicht nach der bewährten Haudrauf-Methode umgehen, indem ich dem Client von Hand den Server unterschiebe? Kann der Client z.B. auch das Pipe Advertisement des Servers lesen und damit eine Pipe erstellen, um sich mit dem Server zu verbinden?


Ja, kann er. Beispiele finden sich in den tutorials: http://platform.jxta.org/source/browse/platform/www/java/tutorial/examples/PipeExample/


Naja, eingebaut hab ich’s jetzt mal, ob es funktioniert, weiß ich noch nicht.
Noch eine Frage: Wie kann ich auf eine Nachricht von der Gegenstelle warten? Ich hab das jetzt so gemacht:
Message msg = bidipipe.getInputPipe().poll(10000);
Da kommt aber immer null raus. Und 10 Sekunden wartet der ja gleich gar nicht. Exceptions treten keine auf, das würde ich (mangels Exception handler) merken. Asynchron will ich das auf gar keinen Fall machen. Sowas ginge vielleicht in JavaScript oder irgendwo, wo es closures gibt, aber in Java ist der Aufwand dafür viel zu groß, für jede winzige Antwort im Protokoll eigens eine Funktion zu schreiben und den gesamten Zustand da rein zu befördern.
Ich weiß, meine Fragerei nervt ganz arg, heute abend geb ich das Teil auch ab, egal in welchem Zustand. Nächste Woche hab ich dafür keine Zeit mehr. Danke für eure Unterstützung bis dahin.


@Erik: Danke, dass du deinen Service laufen laesst! Endlich hat mein Client mal jemanden gefunden, weil meinen eigenen Server findet er nicht :[. Hier ist mein Code, was ist daran falsch?

                        ModuleClassAdvertisement moduleclass = (ModuleClassAdvertisement) AdvertisementFactory.newAdvertisement (ModuleClassAdvertisement.getAdvertisementType ());
                        moduleclass.setName ("JXTAMOD:LibraryService");
                        ModuleClassID mcid = IDFactory.newModuleClassID ();
                        moduleclass.setModuleClassID (mcid);
                        disco.publish (moduleclass);
                        disco.remotePublish (moduleclass);

                        ModuleSpecAdvertisement modulespec = (ModuleSpecAdvertisement) AdvertisementFactory.newAdvertisement (ModuleSpecAdvertisement.getAdvertisementType ());
                        modulespec.setName ("LibraryService");
                        modulespec.setVersion ("1.0");
                        modulespec.setCreator ("siwahofe");
                        modulespec.setModuleSpecID (IDFactory.newModuleSpecID (mcid));
                        modulespec.setSpecURI("http://www4.informatik.uni-erlangen.de/Lehre/WS05/V_MW/Uebung/aufgaben/a8.pdf");

                        // PipeAd erstellen / einlesen
                        PipeAdvertisement pipead = PipeAdvertisementCreator.createPipeAd ("siwahofe.adv", net);
                        modulespec.setPipeAdvertisement (pipead);

                        disco.publish (modulespec);
                        disco.remotePublish (modulespec);

                        System.out.println ("ModuleClassAd and ModuleSpecAd containing PipeAd published.");

Wow, ich finde eure beiden Server jetzt!
Nur leider kann mein Client noch nicht auf die Serverantwort warten.


Kommunikation über die BiDiPipe ist asynchron. Über das PipeMsgListener Interface kannst du auf Antworten warten. Beim Connect kannst du einen PipeMsgListener angeben, der dann die Messages von der Gegenseite erhält.


Und wofür gibt es dann die poll()-Methode, mit der Option, ein Timeout anzugeben, und warum liefert diese Methode laut Spezifikation ein Message-Objekt zurück? Ok, warte, ich mach mal nen sleep(2000) davor, mal schauen, was passiert. - Ne, hilft nicht.

Update: Das Auffinden der Server scheint eher zufällig zu verlaufen. Eben grad hab ich meinen eigenen Server zum ersten Mal gesehen. Beim nächsten Programmstart war er wieder weg.


@Steppenwolf: Also mein Einlesen des pipe.adv sieht bissl anders aus:

System.out.println("Reading in foo.adv");
				FileInputStream is;
				try {
					is = new FileInputStream("foo.adv");
				} catch (IOException e) {
					PipeAdvertismentCreator advcreator = new PipeAdvertismentCreator("foo.adv", netPeerGroup);
					advcreator.createAdvertisment();
					is = new FileInputStream("foo.adv");
				}
					
				
				try {
					XMLDocument document = (XMLDocument) StructuredDocumentFactory.newStructuredDocument(MimeMediaType.XMLUTF8, is);
					pipeAdv = (PipeAdvertisement)
					AdvertisementFactory.newAdvertisement(
							document);
					is.close();
				} catch (Exception e) {
					System.out.println("failed to read/parse pipe advertisement");
					e.printStackTrace();
					System.exit(-1);
				}
				
				
				// Store the pipe advertisement in the spec adv.
				// This information will be retrieved by the client when it will
				// connect to the service
				mdadv.setPipeAdvertisement(pipeAdv);
		
				
				// Ok the Module advertisement was created, just publish
				// it in my local cache and into the NetPeerGroup.
				discovery.publish(mdadv);
				discovery.remotePublish(mdadv);
				
				// we are now ready to start the service
				// create the input pipe endpoint clients will
				// use to connect to the service
				serverPipe = new JxtaServerPipe(netPeerGroup, pipeAdv);

Was mir auch aufgefallen ist, dass im .jxta Verzeichnis ein Cache mit gefundenen Diensten angelegt wird. Vielleicht gibt es da Probleme, weil irgendwas mit der selben ID schon im Cache is und deine Änderungen vom Client nicht gefunden werden. Bei mir hat löschen das Caches manchmal geholfen. Vielleicht das auch mal probieren.


Also gelistet bekomme ich jetzt alle 4 Server - verbinden geht aber nur mit Legolas. Macht ihr denn auch irgendwo ein accept?


Schon, aber mein Server läuft immer nur kurz, solange der Client läuft halt. Die Anfragen kommen bei meinem server schon auch an, aber der Client kann die Antwort nicht empfangen.