Now that the "server" end of the P2P service has been written, it's
time to write the "client" end. The HelloService
interface provides one method, sendMessage, that will
open an output pipe to a random peer's input pipe and send it a
message.

// the method that the application may call to send
// a message to another random peer running the HelloService
public void sendMessage() {
// send out a query to all peers in our peer group
// looking for advertisements of pipes that are
// prefixed with "HelloService:" as the pipes
// for the HelloService are all named like that
this.discovery.getRemoteAdvertisements( null, Discovery.ADV, "name", "HelloService:*", 10 );

// wait 5 seconds for all the responses to come
// in and be incorporated into the platform's cache
try {
Thread.sleep( 5000 );

// construct a message with the sender
// name's as part of the object
Message helloMessage = this.pipes.createMessage();
helloMessage.push( "sender", new ByteArrayInputStream( this.peerGroup.getPeerID().toString().getBytes() ) );

// start the application -- all that is done here is to call
// the sendMessage method on the hello service
public int startApp( String[] arg ) {
// call the one method on the service
this.helloService.sendMessage();

Running Hello JXTA

Running this code is harder than is ideal. The JXTA Java platform
is presently optimized to run the JXTA Shell. Launching the Shell
prepares the platform to run JXTA (it creates a
jxtaConfig file and a PlatformPeerGroup
advertisement directory in the current working directory), so you have
to launch the Shell once to allow it to configure the node. Then you
can terminate the shell and edit the jxtaConfig and the
PlatformPeerGroup files to make the platform do what we
want it to do.

The jxtaConfig properties file contains information
that's used to create the PlatformPeerGroup advertisement
file that the node uses to configure itself. There are two lines to
edit. First, change the value of the isRendezvous
property to "true". This peer will act as a rendezvous for its
specific peer group (a discussion of rendezvous and router peers is
beyond the scope of this article). Second, change the value of
InitialNetPeerGroupAppCode to the class name of the
HelloApp. If you look carefully, you will notice
InitialNetPeerGroupAppCodeURL which ideally would be set
to a URL from which the platform could download the application code.
This property will be ignored if the application classes are in the
classpath when the platform's invoked.

PlatformPeerGroup is the group advertisement (XML
document) for the group that the platform boots into. Modify the
value of the Name tag to HelloPeerGroup,
which will cause this platform to boot into its own custom peer group,
separate from the default network peer group. Then modify
isRendezvous to "true". Finally, we need to add a new
service advertisement to this peer group so that the platform will
boot the HelloService. Add the following advertisement
at the end of the Services element, which is the advertisement passed
to the HelloServiceImpl upon initialization:

When the platform is restarted, it will boot into the
HelloPeerGroup while running the
HelloService. It will create an input pipe, create an
output pipe, connect the two together, and send a message. If you are
lucky (or are running two peers), then the application will connect to
another service and send it a message containing its peer ID.
Otherwise, the service will probably connect to its own pipe and
sending itself a message.

Sun's Java binding for JXTA is a long way from being completed.
The code needs to mature before developers can use it to develop
robust P2P applications. However, by building toy projects and
learning the terminology along with the basic concepts, developers
will be better poised to use it when it matures.

Raffi Krikorian
makes a career of hacking everything and anything. Professionally,
he is the founding partner at Synthesis Studios: a technological design
and consulting firm that orchestrates his disjointed train of thought.