Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

JVM Languages

JXTA & Peer-to-Peer Networks


Jun03: JXTA & Peer-to-Peer Networks

Sing is an author and consultant, and his most recent book is Early Adopter JXTA: P2P Java (Wrox Press, 2001). He can be reached at [email protected].


Peer-to-peer networks have unique qualities that distinguish them from conventional, loosely distributed client/server networks, including the potential for network composition to dynamically and continuously change, as peers join and leave. Consequently, it is often necessary for many peer-to-peer (P2P) applications to determine the "presence" of a particular peer. In this article, I examine the difficulty in creating a generic presence solution, then present a workable solution for a P2P chat application on a JXTA P2P network. The presence solution I present is built on TINI, a Java-based embedded controller from Maxim/Dallas Semiconductors. For more information on TINI, see "A Tiny Board with Big Possibilities," by Al Williams (DDJ, October 2000).

P2P Network Fundamentals

P2P networks are usually introduced by contrasting their topological architectures against the more familiar multitiered client/server. Often, the network is described as a network with only clients and no servers.

An alternate approach to understanding P2P networks begins by examining features that P2P networks must deliver to users, then works backwards to achieve it. In other words, you examine the problems to solve, then come up with solutions. Not only is this approach more intuitive for the engineering-minded, but it is also more fun.

So, a P2P network is a spontaneous, continuous union of connected machines, each sharing and exploiting resources—content, bandwidth, and so on—brought collectively to the network. It is spontaneous because its constituency is constantly changing. Machines and users log on/off the network at any time, and failure on a single machine may occur at any time. The features/services delivered by the P2P network must be relatively unaffected by this constantly changing constituency and network topology. This means there's no dependency on one or more dedicated server machines.

For a typical P2P network to be useful, a critical mass of constituents needs to be continuously connected. Why? Because the network itself is delivering the desired features and/or functionality to end users, not a particular site, server, or service. Desirable features and/or functionality usually center around the sharing of collective resources, contributed by all (or a subset) of the connected constituents. Shared resources may include content, bandwidth, CPU cycles, storage, connectivity, or other specialized capabilities. For example, distributed chat systems on P2P networks share bandwidth, connectivity, and storage within the network by caching and propagating user messages between the constituency.

There are a number of engineering problems to be solved when designing P2P networks and/or applications, including heterogeneous connectivity, discovery, and presence.

Although constituents in a P2P network are connected, they may not be connected in the same physical way. They can be based on completely different hardware pieces (supercomputers, PCs, PDAs, notebook computers, soda machines, heart pacemakers, and the like) running completely different software, and connected, using completely different networking/communication technologies. A generic P2P network technology must cope with and work in a diverse world of potential constituents. In addition, it must be able to route communication messages intelligently across this heterogeneously connected network, and heal itself should the heterogeneous connections break up.

Figure 1 illustrates a P2P network consisting of a PDA, soda machine, three PCs, two notebooks, supercomputer, and pacemaker—all connected using dissimilar hardware and communicating with different networking/communications technology. While the peers are not directly connected physically, the P2P network should make them logically so. This means that a doctor with a PDA and P2P application can have real-time access to pacemaker statistics from patients who are also connected to the network. Should the user on notebook 1 turn off her notebook, the P2P networking software on the PDA reestablishes a physical connection to another peer (say PC 1 via Wi-Fi), transparent to users and applications.

When users/machines join the P2P network, they need to find out what other peers are there, who to send communication messages to, and what features/functionalities are available. Since the network topology is constantly changing, network discovery must be performed dynamically—and the process must be continuous while the peer is connected to the network.

Because we currently live in a client/server world, familiar conventions such as presence are hard to give up. Presence is the ability to determine if specific peers in P2P networks are present at any moment. To determine presence, you must first be able to uniquely identify the possible entities. Presence becomes controversial if the entities are human users, and the P2P network spans the Internet. Other than being controversial, the idea of knowing absolutely (at some point in time) if users or systems are connected to the P2P network goes against the grain of spontaneity and dynamism, which are cornerstones of a true P2P network.

Fortunately, if you are working within a specific application domain (such as instant messaging systems) and aren't concerned about generic presence systems, you can use JXTA to create highly usable solutions to the presence problem.

JXTA: A Workable P2P Substrate

JXTA (http://www.jxta.org/) is an open-source development project for creating a P2P substrate—applicable to any hardware or software platform—that simplifies the creation of P2P-based applications and enhances interoperability of different P2P applications. While retaining a Java heritage, JXTA is actually the specification of a standard set of "minimal denominator" protocols. These protocols are specified independent of programming language, hardware, and even networking and communications technology. This protocol relies on the minimal ability to pass structured data messages between participating peers. Consequently, devices or machines can become JXTA peers as long as they can source or sink communication messages (either textual XML or binary).

A protocol-based solution partially solves the heterogeneous connectivity problem—JXTA protocol messages can flow through systems that differ in hardware, software, and communications technology as long as they are connected and can manipulate and/or parse messages. The other half of the heterogeneous connectivity problem is the required ability to heal the network when peers connect/disconnect. Solving this problem is more involved. Figure 2 illustrates the stack of components that addresses this problem.

First, each peer has a decentralized address (ID) in the network. This address is generated without any centralized authority (unlike IP addresses). The virtual routing and resolving layer binds this address to an actual physical network endpoint when messages are routed between peers. This binding is done as late as possible to accommodate last minute changes in the network topology. But even binding as late as possible may fail due to instantaneous topological changes. In these situations, the JXTA resolver (that is, code for binding address to endpoint) performs a distributed query to determine the latest route. The endpoint routing protocol in the JXTA protocol suite is responsible for this. (For details on how the JXTA components stack operates, see my book Early Adopter JXTA, Wrox Press, 2001; ISBN 1861006357.)

Solving Discovery Problems

Bootstrap discovery is handled in JXTA via the peer discovery protocol. When peers bootstrap in a JXTA network, they advertise themselves by sending protocol messages (advertisements) to the network of rendezvous, whose members cache and propagate these advertisements amongst themselves, following a monitor-cache-propagate pattern. Therefore, for one peer to locate another, it only has to query its nearest rendezvous. While this method of discovery works on top of the heterogeneous connectivity often found in the P2P network, other more optimized methods of discovery are available for specialized situations (on Java implementation over TCP/IP networks, for example, UDP broadcast or multicast can be used to discover peers within a LAN or multicast group).

True to their P2P heritage, JXTA peers follow a monitor-cache-propagate pattern with regard to interesting information. During their lifetimes (that is, while connected and functional on the network), JXTA peers monitor and observe information on the network. This information may contain ID and location of other peers, the announcements of other services that are (or became) available on the network, plus other information of application interest (file location, segments of files being shared, and so on).

As they monitor for information flowing through the network, JXTA peers may selectively store (cache) some local knowledge for later use. Of course, most information cached quickly becomes stale as peers come and go in the network. However, as long as these peers stay connected to the network, the information is relatively up to date. However, if peers disconnect/reconnect, they have at least a startup view that is usable to bootstrap again. To quickly familiarize themselves with the network after a period of absence (or the first time a network is joined), peers depend on the propagation of knowledge with other connected peers.

Propagation of knowledge relies on cached information and dynamic queries. New peers starting up and/or rejoining the P2P network must query a subset of known peers, acting as rendezvous (either by human configuration or located from a previously cached list of peers), for the most current network information. Therefore, it is vital that other peers on the P2P network share in this information. By sharing the most information, P2P networks let new peers quickly come up to speed with network information.

A Presence Solution for JXTA

In itself, JXTA does not provide a solution to the presence problem. Here, however, I present a "good enough" implementation, but for a very specific case—a chat application.

MyJXTA (also known as "Instant P2P"), the showcase application in the JXTA network, combines a group chat, one-on-one chat, and filesharing application into one application. For this example, I create a workable presence solution in the context of the chat application. This presence solution enables peers in the chat room to perform a query similar to davids?, meaning, "Did anyone see davids recently?" Since it isn't possible in the pure JXTA context to guarantee that a peer is connected and reachable at any moment, most chat-room users will be satisfied with answers such as: "Yes, we last heard from davids just five minutes ago" or "No, davids has not joined the chat room at all."

This JXTA service is called SimplePresence. To activate it during the chat, you only need to format the chat message into one of the commands in Table 1. Figure 3 is the SimplePresence service in action. In this case, the service is set to monitor posts from a user named "davids," by the user "Kauaian." SimplePresence runs independently from any peers that may be using it. Ideally, the peers hosting SimplePresence should be up most of the time—or even be redundantly implemented. By using an embedded, low-cost platform such as TINI to implement such a service, you can provide a reliable service (perhaps even redundant) without tying up expensive standalone PC servers.

The JXTA-For-TINI project (http://tini.jxta.org/) is a community project owned by Sean Kelly ([email protected]). The project currently provides a TINI-compatible library to use the relay service provided by the JXME project (http://jxme.jxta.org/). (JXME is JXTA on J2ME platforms.) The JXME relay service enables PDA and other limited-resource Java devices to run JXTA by delegating most of the storage, memory, and computation intensive tasks to the proxy service running on a more powerful peer. At the time of writing, JXTA 2.0 has just become available. JXTA 1.0 and JXTA 2.0 are not compatible on the protocol level. Both JXME and TINI for JXTA work only with JXTA 1.0 proxy service at this time.

The source code for the SimplePresence service is in the DDJFinder.java file (available electronically; see "Resource Center," page 5). Take a look at the main() method (Listing One) to see how the pieces fit together. The only argument required by the DDJFinder constructor is the URL of the proxy service. The main method first initializes the service, then calls the processMessages() method. Listing Two is the init() method that first creates a PeerNetwork instance using the static PeerNetwork.createInstance() call. This is followed by a connection to the JXME proxy via a connect() method call, which starts the bootstrapping process on the proxy for this new peer.

Listing Three is the processMessages() method, which stays in a tight loop polling for messages on a JXTA pipe using a call to the listen() method of PeerNetwork. Every incoming message is parsed to see if it is a command; see the isCommand() helper method (Listing Four; available electronically). Additionally, it also examines the sender to see if it is someone that the service is currently tracking. If the sender is being tracked, the date and current date/time is logged in the private Hashtable called presenceDB. See the logSender() helper method in Listing Four, which encapsulates the command processing logic in the processMessages() helper method.

You don't need to have a TINI to test the DDJFinder service. The TINI-For-JXTA development environment lets you compile using any JDK 1.1 (or later) environment and test the code on a local PC. However, it does take some work to set up the TINI-For-JXTA development environment; for details, see the file README.TXT (available electronically).

DDJ

Listing One

public static void main(String[] argv) {
    if (argv.length != 1) {
        System.err.println("Usage: DDJFinder proxyServerURL");
        System.exit(1);
    }
       DDJFinder myFinder = new DDJFinder(argv[0]);
       myFinder.init();
       myFinder.processMessages();
}

Back to Article

Listing Two

public void init() {
try {
        System.err.println("Creating peer network...");
        peerNetwork = PeerNetwork.createInstance(serviceName);
        System.err.println("Connecting to " + proxyURL);
        peerNetwork.connect(proxyURL, null);
        }
   catch (Exception ex) {
            System.err.println("Problem connecting to JXTA network...");
                            ex.printStackTrace();
        }
    }
    

Back to Article

Listing Three

public void processMessages()  {
     try {
               System.err.println("Listening to pipe " + IP2P_PIPE_ID);
         peerNetwork.listen(serviceName, IP2P_PIPE_ID, "JxtaPropagate");
         System.err.println("Ready.");
         while(true) {
             Message msg = pollForMsg();
                     if (! isCommand(msg))
                            logSender(msg);
                     else
                         {
                             if (!isTerminate(msg))
                        sendMessage(peerNetwork,processCmd(msg),serviceName);
                              else
                                  break;
                          }
                    }// of while
     } catch (Exception ex) {
         System.err.println("Error during message processing");
         ex.printStackTrace();
         System.exit(1);
     }
    }

Back to Article


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.