<length><type><data>
where <length>
and <type>
are 2 bytes each.
<data>
portion of the message is a plain ASCII string.
\r\n
login [CLIENT]
where the client data is
<nick> <password> <port> "<client-info>" <link-type> [ <num> ]
e.g. foo badpass 6699 "nap v0.8" 3
(3 is 33.6 kbps)
www.napster.com
,
so directory discovery is trivial.
LOGIN newmarch XXX
POST http://<host>/cgi-bin/P_handler
Content-Type: application/P
Content-Length: ...
LOGIN newmarch XXX
HTTP/1.1 200 OK
Content-Type: application/P_response
<response>
response
Peer discovery can be done in a variety of ways:
Searching involves
This uses the configuration file
MembershipAuthenticator=NullAuthenticator
MembershipIdentity=somebody
InitialNetPeerGroupAppCode=Server
InitialNetPeerGroupAppCodeURL=http:/www.jxta.org/download/jxta.jar
The server is
/*
* Copyright (c) 2001 Sun Microsystems, Inc. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Sun Microsystems, Inc. for Project JXTA."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact Project JXTA at http://www.jxta.org.
*
* 5. Products derived from this software may not be called "JXTA",
* nor may "JXTA" appear in their name, without prior written
* permission of Sun.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of Project JXTA. For more
* information on Project JXTA, please see
* <http://www.jxta.org/>.
*
* This license is based on the BSD license adopted by the Apache Foundation.
*
*/
/**
* Service Application: This the server side of a JXTA-EX1
* application. This application starts a JXTA service that receives a
* message from a listening pipe. The Service advertisement is published in
* the NetPeerGroup. Clients can discover the service advertisement and
* create output pipes to connect to the service. The server application
* creates an input pipe that waits to receive messages. Each message
* received is printed to the screen. We run the server as a daemon
* in an infinite loop, waiting to receive messages.
*/
import java.io.InputStream;
import java.io.StringWriter;
import net.jxta.platform.Application;
import net.jxta.document.Advertisement;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.StructuredTextDocument;
import net.jxta.document.MimeMediaType;
import net.jxta.endpoint.Message;
import net.jxta.pipe.Pipe;
import net.jxta.pipe.PipeID;
import net.jxta.pipe.InputPipe;
import net.jxta.peergroup.PeerGroup;
import net.jxta.peergroup.PeerGroupID;
import net.jxta.protocol.ServiceAdvertisement;
import net.jxta.protocol.PipeAdvertisement;
import net.jxta.discovery.Discovery;
public class Server implements Application {
private Discovery disco; // Discovery service
private Pipe pipes; // Pipe Service
private InputPipe myPipe; // input pipe for the service
private Message msg; // pipe message received
private PeerGroupID gid; // group id
public Server() {
}
// Init method is called by the platform, with the
// current peergroup, in our case we are running from the
// NetPeerGroup. So the Platform pass us the NetPeerGroup
// pointer and the group advertisement if we need something
// to look for in the PeerGroup Advertisement.
public void init(PeerGroup group, Advertisement adv) {
System.out.println("Start the Server daemon");
// get the peergroup service we need
disco = group.getDiscovery();
pipes = group.getPipe();
gid = group.getID();
}
public int startApp (String[] args) {
try {
// First create the Service advertisement associated with the service
// We build the service Advertisement using the advertisement
// Factory class by passing it the type of the advertisement we
// want to construct.
ServiceAdvertisement srvadv = (ServiceAdvertisement)
AdvertisementFactory.newAdvertisement(
ServiceAdvertisement.getAdvertisementType());
// Setup some of the information field about the servive. In this
// example, we just set the name, provider and version and a pipe
// advertisement. The service creates an input pipes to listen
// on this pipe endpoint.
//
srvadv.setName("JXTA-EX1");
srvadv.setProvider("jxta.org");
srvadv.setVersion("Version 1.0");
// Create a pipe advertisement for the Service. The client MUST use
// the same pipe advertisement to talk to the server. When the client
// discovers the service advertisement it will extract the pipe
// advertisement to create its pipe.
//
// In this sample code the pipeid is created from the peergroup id.
// In the generic case the server should publish its service
// advertisement and persit the service advertisement after reboot
// so it can use the pipe.
PipeAdvertisement pipeadv = (PipeAdvertisement)
AdvertisementFactory.newAdvertisement(
PipeAdvertisement.getAdvertisementType());
pipeadv.setName("Pipe JXTA-EX1");
// We just pick the current id of the group and use it to
// make the unique Id. We are guaranteed that the NetPeerGroup
// Id is unique.
pipeadv.setPipeID(new PipeID(gid));
// Store the pipe advertisement in the service advertisement
srvadv.setPipe(pipeadv);
// display the advertisement as a plain text dcoument.
StructuredTextDocument doc = (StructuredTextDocument)
srvadv.getDocument(new MimeMediaType("text/plain"));
StringWriter out = new StringWriter();
doc.sendToWriter(out);
System.out.println(out.toString());
out.close();
// Ok the Service advertisement was created, just publish
// it in my local cache and to my peergroup. This
// is the NetPeerGroup
disco.publish(srvadv, Discovery.ADV);
disco.remotePublish(srvadv, Discovery.ADV);
// we are now ready to start the service
// create the input pipe endpoint client can
// use to connect to the service
myPipe = pipes.createInputPipe(pipeadv);
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Server: Error publishing the service");
}
// Ok no way to stop this daemon, but that's beyond the point
// of the example!
while (true) { // loop over every input received from the service
// pipe
System.out.println("Waiting for client messages to arrive");
try {
// Listen on the pipe for a client message
msg = myPipe.waitForMessage();
} catch (Exception e) {
myPipe.close();
System.out.println("Server: Error listening for message");
return 1;
}
// Create the input stream to extract the body of the message
InputStream ip = null;
try {
// NOTE: The client and service have to agree on the tag names.
// this is part of the Service protocol defined
// to access the service.
ip = msg.pop ("DataTag");
if (ip != null) {
// read the data
byte[] buffer = new byte [ip.available()];
int res = ip.read (buffer);
System.out.println("Server: receive message: " + new String(buffer));
ip.close();
} else
System.out.println("Server: error could not find the tag");
} catch (Exception e) {
System.out.println("Server: error receiving message");
}
}
}
// no much to be done here!
public void stopApp () {
}
}
This uses the configuration file
MembershipAuthenticator=NullAuthenticator
MembershipIdentity=somebody
InitialNetPeerGroupAppCode=Client
InitialNetPeerGroupAppCodeURL=http:/www.jxta.org/download/jxta.jar
The client is
/*
* Copyright (c) 2001 Sun Microsystems, Inc. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Sun Microsystems, Inc. for Project JXTA."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact Project JXTA at http://www.jxta.org.
*
* 5. Products derived from this software may not be called "JXTA",
* nor may "JXTA" appear in their name, without prior written
* permission of Sun.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of Project JXTA. For more
* information on Project JXTA, please see
* <http://www.jxta.org/>.
*
* This license is based on the BSD license adopted by the Apache Foundation.
*
*/
/**
* Client Application: This is the client side of the EX1 example that
* looks for the JXTA-EX1 service and connects to its advertised pipe. The
* Service advertisement is published in the NetPeerGroup
* by the server application. The client discovers the service
* advertisement and create an output pipe to connect to the service input
* pipe. The server application creates an input pipe that waits to receive
* messages. Each message receive is displayed to the screen. The client
* sends an hello message.
*/
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Enumeration;
import net.jxta.platform.Application;
import net.jxta.document.Advertisement;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.StructuredTextDocument;
import net.jxta.document.MimeMediaType;
import net.jxta.endpoint.Message;
import net.jxta.pipe.Pipe;
import net.jxta.pipe.PipeID;
import net.jxta.pipe.OutputPipe;
import net.jxta.peergroup.PeerGroup;
import net.jxta.id.ID;
import net.jxta.protocol.ServiceAdvertisement;
import net.jxta.protocol.PipeAdvertisement;
import net.jxta.discovery.Discovery;
public class Client implements Application {
private Discovery disco; // Discovery service
private Pipe pipes; // Pipe Service
private OutputPipe myPipe; // Output pipe to connect the service
private Message msg;
public Client() {
}
// Init method is called by the platform, with the
// current peergroup, in our case we are running from the
// NetPeerGroup, so the Platform passes us the NetPeerGroup
// pointer and the group advertisement, if we need something
// to look for in the PeerGroup Advertisement, like configuration
// parameters.
public void init(PeerGroup group, Advertisement adv) {
// Let's initialize the client
System.out.println("Start the Client");
// get the peergroup services we will use:
// Discovery to discover the server service
// Pipe to create an output pipe to the service
disco = group.getDiscovery();
pipes = group.getPipe();
}
public int startApp (String[] args) {
try {
// Let's try to locate the service advertisement
// we will loop until we find it!
//
System.out.println("searching for the JXTA-EX1 Service advertisement");
Enumeration enum = 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
//
enum = disco.getLocalAdvertisements(Discovery.ADV
, "Name"
, "JXTA-EX1");
// Ok we got something in our local cache does not
// need to go further!
if ((enum != null) && enum.hasMoreElements()) break;
// We could not find anything in our local cache, so let's send a
// remote discovery request searching for the service
// advertisement.
disco.getRemoteAdvertisements(null
, Discovery.ADV
, "Name"
, "JXTA-EX1",1);
// 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 notification.
Thread.sleep(2000);
} catch (Exception e){
}
} catch (IOException e){
// found nothing! move on
}
System.out.print(".");
}
System.out.println("we found the advertisement");
// Ok get the advertisement
ServiceAdvertisement srvadv = (ServiceAdvertisement) enum.nextElement();
// let's print the advertisement as a plain text document
//
StructuredTextDocument doc = (StructuredTextDocument)
srvadv.getDocument(new MimeMediaType("text/plain"));
StringWriter out = new StringWriter();
doc.sendToWriter(out);
System.out.println(out.toString());
out.close();
// we can extract the pipe advertisement from the service
PipeAdvertisement pipeadv = srvadv.getPipe();
// create the output pipe endpoint to connect
// to the client, try 3 times to bind the pipe endpoint to
// the listening endpoint pipe of the service
for (int i=0; i<3; i++) {
myPipe = pipes.createOutputPipe(pipeadv, Pipe.NonBlocking, 5000);
}
// create the data string to send to the server
String data = "Hello my friend!";
// create the pipe message
msg = pipes.createMessage();
// store the client data into the message with the tag "DataTag"
// as an inputstream
ByteArrayInputStream ip = new ByteArrayInputStream (data.getBytes());
msg.push ("DataTag", ip);
// send the message to the service pipe
myPipe.send (msg);
System.out.println("message \"" + data + "\" sent to the Server");
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Client: Error sending message to the service");
}
// Ok we are done, just exit
System.exit(0);
return 0;
}
// no much to be done here!
public void stopApp () {
}
}