在jxta里面,所有的资源都是通过广告来发布的,这里的服务业不例外,在这里的服务 发布里面有两个很总要的概念,
• ModuleClassAdvertisement— defines the service class; its main purpose is to formally document the
existence of a module class. It is uniquely identified by a ModuleClassID.
• ModuleSpecAdvertisement — defines a service specification; uniquely identified by a ModuleSpecID.
Its main purpose is to provide references to the documentation needed in order to create conforming
implementations of that specification. A secondary use is to make running instances usable remotely,
by publishing any or all of the following:
• PipeAdvertisement
• ModuleSpecID of a proxy module
• ModuleSpecID of an authenticator module
• ModuleImplAdvertisement — defines an implementation of a given service specification.
这里的 ModuleClassAdvertisement 仅仅用来告知服务的存在,对等点若是需要访问该服务的话,还需要发现与之关联的 ModuleSpecAdvertisement 广告信息。
而这里的 ModuleSpecAdvertisement 则包含了 对等点节点 要访问该服务所需要的所有相关信息,比如:管道广告信息,通过它才能够连接上所需要的服务。
服务端的代码示例大抵如下:
创建发布 ModuleClassAdvertisement :
ModuleClassAdvertisement mcadv = (ModuleClassAdvertisement)AdvertisementFactory.newAdvertisement(ModuleClassAdvertisement.getAdvertisementType());
mcadv.setName("JXTAMOD:JXTA-EX1");
mcadv.setDescription("Tutorial example to use JXTA module advertisement Framework");
ModuleClassID mcID = IDFactory.newModuleClassID();
mcadv.setModuleClassID(mcID);//通过mcID来建立ModuleClassAdvertisement 与ModuleSpecAdvertisement 的联系
discovery.publish(mcadv);
discovery.remotePublish(mcadv);
创建发布 ModuleSpecAdvertisement :
ModuleSpecAdvertisement mdadv = (ModuleSpecAdvertisement)AdvertisementFactory.newAdvertisement(ModuleSpecAdvertisement.getAdvertisementType());
mdadv.setName("JXTASPEC:JXTA-EX1");
mdadv.setVersion("Version 1.0");
mdadv.setCreator("sun.com");
mdadv.setModuleSpecID(IDFactory.newModuleSpecID(mcID));
mdadv.setSpecURI("http://www.jxta.org/Ex1");
PipeAdvertisement pipeadv = null;
try {
FileInputStream is = new FileInputStream("pipeserver.adv");
pipeadv = (PipeAdvertisement)AdvertisementFactory.newAdvertisement(MimeMediaType.XMLUTF8, is);
is.close();
} catch (Exception e) {
System.out.println("failed to read/parse pipe advertisement");
}
mdadv.setPipeAdvertisement(pipeadv);
discovery.publish(mdadv);
discovery.remotePublish(mdadv);
myPipe = pipes.createInputPipe(pipeadv);
在客户端,通过不断的查找广告(分本地查找和远端查找)来 获取 所需要服务的广告信息,通过它就可以获取 管道信息 来创建管道以达到通讯的目的。客户端代码示例大抵如下:
Enumeration en = null;
while (true) {
try {
/* let's look first in our local cache to see if we have it! We try to discover an adverisement which as the (Name, JXTA-EX1) tag value
en = discovery.getLocalAdvertisements(DiscoveryService.ADV,"Name","JXTASPEC:JXTA-EX1");
// Ok we got something in our local cache does not
// need to go further!
if ((en != null) && en.hasMoreElements()) {
break;
}
// nothing in the local cache?, let's remotely query
// for the service advertisement.
discovery.getRemoteAdvertisements(null,DiscoveryService.ADV,"Name","JXTASPEC:JXTA-EX1",1, null);
// The discovery is asynchronous as we do not know
// how long is going to take
try { // sleep as much as we want. Yes we
// should implement asynchronous listener pipe...
Thread.sleep(2000);
} catch (Exception e) {}
} catch (IOException e) {
// found nothing! move on
}
System.out.print(".");
}
System.out.println("we found the service advertisement");
// Ok get the service advertisement as a Spec Advertisement
ModuleSpecAdvertisement mdsadv = (ModuleSpecAdvertisement)en.nextElement();
try {
// let's print the advertisement as a plain text document
StructuredTextDocument doc = (StructuredTextDocument)mdsadv.getDocument(MimeMediaType.TEXT_DEFAULTENCODING);
StringWriter out = new StringWriter();
doc.sendToWriter(out);
System.out.println(out.toString());
out.close();
// we can find the pipe to connect to the service
// in the advertisement.
PipeAdvertisement pipeadv = mdsadv.getPipeAdvertisement();
// Ok we have our pipe advertiseemnt to talk to the service
// create the output pipe endpoint to connect to the server
myPipe = pipes.createOutputPipe(pipeadv, 10000);
}
// send the message to the service pipe
myPipe.send (msg);