http://www.developer.com/java/j2me/article.php/1501461/JXTA4J2ME-Implementation-Architecture.htm
In the first part of this series of articles, we discussed the basic JXTA architecture and elaborated how it can coordinate with J2ME edge devices to become part of an integrated application framework in a truly distributed and heterogeneous environment. Based on this ability of the JXTA and J2ME technologies to work together, we explained why Java Wireless programmers should care about using this combination of technologies. In the second part, we presented JXTA4J2ME as a messaging framework. We listed the common features of all messaging applications and briefly described how Enterprise Java offers these features. We then showed how a JXTA4J2ME implementation matches the same features and how wireless application developers can use the high-level JXTA4J2ME API in a messaging application. This installment will take you on a journey into the JXTA4J2ME implementation to see what's inside. In this article, we will discuss the following issues: Readers are encouraged to go through Part 2 of this series before reading this third installment. Part 2 discusses the use of the JXTA4J2ME API, which is important to understand the concepts presented in this article. Recall from our discussion in the last article that PeerNetwork is the main class that wraps almost all JXTA4J2ME functionality. Therefore, this class is a good point to start digging to see what's inside. While looking at the details of the PeerNetwork class, we will explain how it works, how it manages communication, what protocol format the JXTA relay expects, what data the relay returns to the PeerNetwork class, and how the PeerNetwork class loads and manages protocol data primitives internally. You will always use the PeerNetwork.createInstance static factory method to instantiate a PeerNetwork object. The createInstance method internally calls the PeerNetwork constructor. All PeerNetwork constructors are kept private by the class designers, to control the creation of PeerNetwork objects. Once a PeerNetwork object has been instantiated, you will call its connect method as explained in the second part. The PeerNetwork.connect method in the current JXTA4J2ME implementation internally manages all connection-related issues through a helper class named HttpMessenger. The HttpMessenger class is not exposed directly to a JXTA4J2ME client application, as it only serves as a sandwiched layer between the PeerNetwork API and the underlying J2ME implementation. The main advantage of having a sandwiched layer is depicted in Figure 1. As shown in Figure 1, the HttpMessenger class comes in two flavors, one for Connected Device Configuration (CDC) and one for Connected Limited Device Configuration (CLDC). CDC and CLDC are two configurations for wireless devices. CLDC, as its name suggests, is meant for devices that are more limited in their resources as compared to CDC devices. Examples of CLDC devices are communicators, automobile entertainment devices, digital refrigerators, and so forth. On the other hand, examples of CLDC devices are mobile phones and pagers. The HttpMessenger class, therefore, provides a bit of abstraction over the two configurations and takes care of the differences in different J2ME configurations. If more configurations are introduced in the future, you will simply need to re-implement the HttpMessenger class for each configuration and the rest of JXTA4J2ME will work as such. The HttpMessenger class has a method named connect, which is responsible for creating a connection with the JXTA relay. The PeerNetwork.connect method internally calls the HttpMessenger.connect method, which in turn sends an "obtainLease" request to the relay using the J2ME classes for HTTP communications. Following is a typical obtainLease HTTP request: This is a simple HTTP request that uses the post method and sends the JXTA command named "obtainLease". Following is an example of the HTTP response that the relay is expected to return in case of a lease approval: The HttpMessenger.connect method, on receipt of the response from the relay, will first check whether the relay has provided the required lease. If so, it will extract the x-jxta-client value from the request and return it to the PeerNetwork.connect method. The PeerNetwork.connect method will eventually return this value to the calling application to be used in subsequent connection requests (recall our discussion related to the PeerNetwork.connect method in Part 2). Once you have obtained a lease from the relay, you are connected to the JXTA network. You can now start sending different types of messages (for example, search messages) to the JXTA network. Before considering the actual messaging, it is important to understand the format that JXTA4J2ME uses to communicate with the relay. The following section explains the messaging formats involved. Following is a search message that a JXTA relay will understand and recognize as a search message: The actual message does not contain any spaces or line breaks, but we have inserted some spaces and line breaks to improve readability. However, it is still not easy to understand the above message, until we understand the different elements of the message and the different fields of each element. Now, look at the following form of the same message, where we have inserted some comments and put in numbers to identify individual elements of the message: The first line (starting with the string "jxmg") is the message header, which marks the start of a message. An explanation of each field of the message header is as follows: The order of occurrence of the different fields in the message header should remain the same as shown above. You can gather the following points from the explanation of the message header: Now let's have a look at the individual elements of the message. The first element is reproduced below: Recall from the discussion of the Element class constructor in Part 2 that the Element constructor takes four parameters, namely: Name (of the element), These four parameters form the four "fields" of an individual element. Mapping of these four parameters to the different fields is explained below (in the same order as the fields appear in an element): The Element and Message classes in the JXTA4J2ME implementation wrap all this functionality. All you need to do is create individual elements by calling the Element constructor, put all the elements in an array, and then pass on the array to the Message constructor. The Message class will automatically generate the completed message payload when required. As explained in the second part, the search method of the PeerNetwork class performs the searching for you. The PeerNetwork.search method takes two parameters, namely the type of the resource that you want to search (peer, group, or pipe) and a query string (name of the resource that you are looking for). Internally, the search method performs two steps: Consider the following search method call: This method call will internally generate an array of following elements following the message header: We have already discussed the details of the format of the message header and the elements. Now let's see what they mean: The above message consists of five elements, all of which belong to the "proxy" namespace. The first element is the request tag that identifies this message as a request query message. The second element defines the resource that you want to search for. The first parameter that the user supplies (type of the resource to search for) to the PeerNetwork.search method call will be copied as the data field of this element. The third and fourth elements define a name value pair. The current JXTA4J2ME implementation has hard-coded the data field of the third element as "Name", which means the search request will always try to match the names of resources (peer, group, or pipe) with the data string of the fourth element. The fifth element is a request identifier. The relay will include this identifier with the response to identify that the response is for this particular search message. The search message generates a request identifier for each search message call and returns the identifier to the calling application, so that it can keep a record of the identifier to match responses. The search message now needs to be added to the outgoing messages queue. This is the job of a private method named PeerNetwork.sendMessage. The search method will call the sendMessage method and hand the newly authored search message to it. The sendMessage method adds two new elements to the message and then places the Message object to the outgoing messages queue: The first five elements in the above code are the same as those authored by the search method described above. The last two elements (sixth and seventh) are added by the sendMessage method. The sixth element is the address of the (destination) JXTA relay, while the seventh element identifies the (source) J2ME device on the JXTA network. Recall the PeerNetwrk.send message call discussed in the last article. This method is used to send messages to specific pipes in the JXTA network. However, JXTA4J2ME cannot send messages directly to the pipe. Rather, we will send the message to the relay and include appropriate elements in the message that will tell the relay which pipe is to be used as the transport for the message to its destination peer(s). You have seen how a search query message is sent. The message is internally authored and then sent to the JXTA relay. This procedure is similar for sending messages to a pipe. The only difference is that search messages are authored internally inside the PeerNetwork.search method and then a call is made to the sendMessage method. When you want to send your own message to a pipe, you will author it yourself and then call the send method of the PeerNetwork class. The send method will internally call the sendMessage method, which will add its two elements and then adds the message to the outgoing messages queue. The following message consists of nine elements, out of which only two were authored by the client; the rest of the elements were appended by the message sending procedure. The PeerNetwork.poll method call checks for incoming messages on the relay. Internally, it will first check whether there are any outgoing messages in the queue waiting to be sent. It will extract (de-queue) the first message from the queue and append that message to its poll message. If there are no messages, an empty message will be used for polling. It will then call the poll method of the HttpMessenger class, which will send the poll message. As explained above, the HttpMessenger class is here to provide abstraction for various configurations in J2ME. That's why the actual HTTP communication is the responsibility of the HttpMessenger class. Following is a typical HTTP request that will be used for polling: In this article, we have described the internal functioning of JXTA4J2ME classes. We started with the PeerNetwork class and explained the PeerNetwork operation over the sandwiched HttpMessenger class. We also provided sample HTTP messages that request a leased connection into the JXTA network. We then discussed the format of JXTA messages that are exchanged between relays and J2ME devices. Next, we described how messages are authored internally and queued as outgoing traffic. At the end, we discussed the polling procedure that checks with the relay if there are any incoming messages. In the next article, we'll present a list of value-added J2ME applications that can be built using the JXTA set of protocols. We will also discuss the design of a couple of such applications. Bilal Siddiqui is an Electronics Engineer, an XML consultant, and the co-founder of WaxSys, a company focused on simplifying e-Business. After graduating in Electronics Engineering from the University of Engineering and Technology, Lahore, in 1995, he began designing software solutions for industrial control systems. Later, he turned to XML and used his experience programming in C++ to build Web- and WAP-based XML processing tools, server-side parsing solutions, and service applications. He is a technology evangelist and a frequently published technical author. Bilal has also contributed to a couple of books, namely Java P2P Unleashed and Web Services Business Strategies and Architectures. Readers may contact Bilal at bsiddiqui@waxsys.com.
JXTA4J2ME Implementation Architecture
November 15, 2002
The PeerNetwork Class
Instantiating the PeerNetwork Class
Connecting to the Relay

POST /relay HTTP/1.1
Host: 209.25.154.233
Connection: keep-alive
x-jxta-command: obtainLease
Content-length: 0
HTTP/1.1 200 OK
Date: Fri, 01 Nov 2002 07:35:18 GMT
Server: Jetty/4.0.3 (Linux 2.4.9-6smp i386)
Servlet-Engine: Jetty/1.1 (Servlet 2.3; JSP 1.2; java 1.4.0-beta)
x-jxta-num-msg: 0
x-jxta-relay: uuid-59616261646162614A787461503250335F148183A71344
AAADB2A724632A2
8F703
x-jxta-client: uuid-59616261646162614A7874615032503384EB6855E3AD4
6E09696871CC17E
E24C03
x-jxta-lease: 1800000
Content-Length: 0
JXTA Message Format
jxmg 0 01 05 proxy 05
jxel 2 0 07 request 06 search
jxel 2 0 04 type 04 Peer
jxel 2 0 04 attr 04 Name
jxel 2 0 05 value 06 Waxsys
jxel 2 0 09 requestId 01 1
// The message header
jxmg 0 01 05 proxy 05
// List of elements:
1- jxel 2 0 07 request 06 search
2- jxel 2 0 04 type 04 Peer
3- jxel 2 0 04 attr 04 Name
4- jxel 2 0 05 value 06 Waxsys
5- jxel 2 0 09 requestId 01 1
Message header explanation:
jxmg // Message header identifier
0 // Message version
01 // Number of namespaces within the element
05 // Length of the first namespace
proxy // Name of the first namespace
05 // Number of elements in this message
1- jxel 2 0 07 request 06 search
Data,
Namespace, and the
MIME type.
Searching on a JXTA Network
// Assuming "peerNetwork" is a PeerNetwork instance.
int requestId = peerNetwork.search (PeerNetwrok.PEER, "Waxsys");
// The message header
jxmg 0 01 05 proxy 05
// List of elements:
// Identifies the message as a Search request/query
1- jxel 2 0 07 request 06 search
// Type of resource to search for
2- jxel 2 0 04 type 04 Peer
// Attribute of the source to search for.
// It is hard-coded by JXTA4J2ME as "Name"
3- jxel 2 0 04 attr 04 Name
// Name of the resource to search for.
4- jxel 2 0 05 value 06 Waxsys
// Request identifier to match responses.
5- jxel 2 0 09 requestId 01 1
// The message header
jxmg 0 01 05 proxy 07
// List of elements
1. jxel 2 0 07 request 06 search
2. jxel 2 0 04 type 04 Peer
3. jxel 2 0 04 attr 04 Name
4. jxel 2 0 05 value 06 Waxsys
5. jxel 2 0 09 requestId 01 1
6. jxel 1 0 27 EndpointDestinationAddress 84
HTTP://127.0.0.1:8080/urn:jxta:uuid-7.
DEADBEEFDEAFBABAFEEDBABE0000000E05/CrystalGroup
7. jxel 1 0 22 EndpointSourceAddress 95 http://JxtaHttpClientuuid-
59616261646162614A7874615032503384EB6855E3AD46E09696871CC17E/
Sending Messages to a JXTA Pipe
// Message header
jxmg 0 01 05 proxy 09
// Elements authored internally by the PeerNetwoek.send() method:
1. jxel 2 0 07 request 06 send // Send request element
2. jxel 2 0 09 requestId 01 1 // Request identifier
3. jxel 2 0 09 name 08 PipeName // Name of the pipe
4. jxel 2 0 09 id 06 PipeID // Pipe ID
5. jxel 2 0 09 type 11 JxtaUnicast // Type of the pipe
// Elements authored by the client application/JXTA4J2ME user.
// Notice that here we are using the default (empty) namespace.
6. jxel 0 0 04 Name 06 Waxsys // peer name element
7. jxel 0 0 07 Message 04 Hello WaxSys // message for peer
// element
// Two elements authored by the PeerNetwork.sendMessage() method.
8. jxel 1 0 27 EndpointDestinationAddress 84
HTTP://127.0.0.1:8080/urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE0000000
E05/CrystalGroup
9. jxel 1 0 22 EndpointSourceAddress 95 http://JxtaHttpClientuuid-
59616261646162614A7874615032503384EB6855E3AD46E09696871CC17E/
Polling for incoming messages
POST /relay HTTP/1.1
Host: 209.25.154.233
Connection: keep-alive
x-jxta-command: poll
x-jxta-client: uuid-59616261646162614A7874615032503384EB6855E3AD
46E09696871CC17E
x-jxta-timeout: 1000
Content-length: 0
Summary
About the Author
Resources