In This Chapter
- JXTA Defines
- Peer and Groups
- Pipe Bending Protocols
- Rendezvous Protocol
- JXTA Identifiers
By Daniel Brookshier
Now we look at key JXTA concepts and the protocols used. In this chapter, we will reiterate aspects of that protocol from the author’s point of view and in less formal language to ease you slowly into JXTA concepts. The JXTA protocol specification is a formal document that describes a standard for JXTA peers and their behavior. The goal of this chapter is to acquaint you with the concepts in preparation for Chapter 3, “JXTA Protocols,” where we will begin covering Java API.
The following a quote is from the introduction of the JXTA protocol specification:
The JXTA protocols are a set of six protocols that have been specifically designed for ad hoc, pervasive, and multi-hop peer-to-peer (P2P) network computing. Using the JXTA protocols, peers can cooperate to form self-organized and self-configured peer groups independently of their positions in the network (edges, firewalls), and without the need of a centralized management infrastructure.
What this all means is that JXTA is a framework with a set of standards that support peer-to-peer applications. JXTA is not an application, and it does not define the type of applications you write. The protocols defined in the standard are also not rigidly defined, so their functionality can be extended to meet specific needs.
JXTA is made up of three distinct layers. The first is the platform. The platform contains core functionality used by services, which are the second layer. Services provide access to the JXTA protocols. Finally, there are applications that use services to access the JXTA network and utilities. This arrangement should be familiar because it is identical to a standard operating system, where there are three layers consisting of the core operating system, services, and applications.
JXTA adds several new concepts, such as the peer, peer group, pipe, and endpoints. JXTA uses a new concept in peer-to-peer communication and discovery with advertisements, which are XML documents that describe services and information available on the JXTA network. Finally, we have various types of identifiers used to distinguish one item or service from another.
Goals of JXTA
To begin, let’s start with the goals of JXTA. The goals of JXTA are very simple:
- Operating system independence
- Language independence
- Providing services and infrastructure for P2P applications
In essence, the goals of JXTA are to support peer-to-peer programming on any device from a desktop computer to a PDA to a car or washing machine.
JXTA is not a competitor to JINI. Although JXTA can run on devices, such as refrigerators, but that is not the ultimate goal—just something possible given the goals. Many new to JXTA confuse JXTA with JINI because of the many references to devices. JXTA and JINI have similar, but different, goals. JINI is aimed more at discovering and using devices. JINI is also more Java-centric where JXTA specifically uses XML instead of RMI, as does JINI. JINI was also designed to work within the bounds of a local area network, not to interoperate on the Web and across firewalls, as does JXTA. JINI is also more concerned with services located on a particular network, such as a printer, for example. JXTA would more likely be used to communicate with a software service that is not location specific.
There are also conceptual goals. These goals include the following:
- Use groups to organize peers and to give context to services and applications.
- Groups use authentication and credentials to control access and/or enable security at the group level.
- Distribute information about peers and network resources throughout the network.
- Queries are distributed throughout the system.
- Provide an infrastructure for routing and communications between peers. Communication with peers behind firewalls and other barriers is a key part of this goal.
- Provide mechanisms to allow peers to monitor each other and resources.
In addition to these goals, there are several other goals, such as encryption, support for various communications protocols, ease of use, stability, and performance. All of these goals were considered when creating the JXTA protocols and the initial Java API.
Additionally, there were other goals considered by the developers and the Sun Microsystem’s managers:
- Create a system that would enable any device to be added to the JXTA network (similar to JINI).
- Create a system that would enable centralized management of peers within ISPs and corporate Internets.
- Create a system that can support digital rights management. This would foster JXTA’s use in purchasing digital products, such as software, music, movies, and other digital media. File sharing P2P applications that do not account for digital rights will be seen as a legal liability and will be blocked by businesses and ISPs. By respecting intellectual property and copyrights, JXTA managers hope that JXTA will be allowed access.
- Encapsulate and abstract specific core functionality so that commercial applications can be created. In other words, enable manufactures to create appliances or hardware to perform functions similar to traditional networking products, such as routers, firewalls, and hubs. This enables hardware and appliance manufacturers to profit, as well as adds industry and corporate respectability.
The prior list has two key concepts. First, companies need to be able to feel like they have control. Most P2P systems do not have centralized management and are not welcome in most corporate situations. Secondly, the JXTA system needs to produce income for more than just application developers. This means that there needs to be hardware or hardware/software combinations that are sold by vendors. Because Sun Microsystems is in the hardware business as well as software, this is a very important goal.
Given all of the goals, JXTA is designed for industry acceptance, maintainability, robustness, and can be used to fulfill almost any P2P application concept. Because of the many goals, there is resulting complexity. Because the system is complex and there are many methods to implement a P2P platform, the specification is bound to change in the beginning. This chapter was rewritten several times as the specification changed in the early months of development of the JXTA platform.
In general, most of the following will be reasonably stable, but be aware that some name changes or structures may occur. Based on current experience, the differences will be minor and the following should remain mostly current for quite some time.
XML and JXTA
XML is the basis for most of the protocol in JXTA. The key reasons are its ability to be read by many languages and its ability to be validated. XML is also an easy choice just because of its popularity.
Overall, XML is a good choice because it is easy to sell as a protocol. To create a protocol that used a binary format would be more difficult to understand, and parsers would need to be built from scratch. With XML, there are many parsers that can be used, both commercial and free. XML is also becoming a standard for many different industries for representing data, so mixing data with the protocol is as simple as merging two XML documents.
There is a downside to using XML. XML is simply not a compact way to express data. Messages written in XML will be much larger than a binary equivalent. There are techniques that can be used, such as replacing tags with binary tokens or compacting data, but none of these are currently employed in JXTA because there are no widely accepted standards at this time. Consequently, the core JXTA developers have created a simple binary message transport and have used terse language and acronyms for tag names. Unfortunately, this means that the XML used in JXTA is devilishly hard to learn and read.
Because some developers are not familiar with XML, Appendix B, “XML Primer,” has a short primer on XML concepts.
Peer-to-peer networking, such as server-based networking, requires a lexicon of concepts that need to be understood. The concepts are similar to others you are familiar with, except that there are a few twists caused by the needs of a P2P network. Let’s look at the important definitions and concepts that will be critical to understanding JXTA. We’ll return to each of these concepts and discuss them in more detail later in the chapter.
A peer is a virtual communications point. You can have multiple peers on a computer or device. A peer is not the same as a user because a user may have peers on their phone, office/home computer, or other devices. It is also possible to have multiple peers on a single device, not necessarily an ideal situation but good for debugging.
Because a peer is not the same as a user, applications need to abstract the idea of user separately from peers. Any abstraction of users should be viable when a user has access to multiple peers.
Peers are also associated with special network services that they provide. In the reference implementation, peers can share basic services with the rest of the network, such as rendezvous, router, gateway, or a combination. These basic services provide search and communication services. In general, not all peers need to enable these services, but a percentage of them are required to ensure that other peers have access to these services. We will cover the concepts of these services a little later in this chapter.
One Peer On One Computer
Usually only one peer resides on a single platform. We assume a communications model where there is only one peer per device. When P2P is accomplished by a distributed network of computers acting as peers, we get the most value from collaboration, distributed searching, content sharing, bandwidth sharing, distributed processing, and other P2P applications. Nevertheless, there is nothing to preclude multiple peers from residing on a single platform or multi-CPU device. As long as the peers can be viewed as separate entities, there should be no problem, except for consuming extra resources. As a minimum, multiple peers can be launched on a single computer to simulate a network for debugging.
One reason for multiple peers on a single computer is to provide a proxy service for peers that are too small to be a JXTA client. This is true for cell phones or other portable devices. However, with advancements in portable devices, there is less of a need for this type of arrangement. There are cases where you need to do this, but they should be special cases. You should also realize that the same functionality could be created by a group of individual peers, each peer acting as a proxy for the telephone peer.
- Context switching—The number of peers you need to run are greater than the capacity of the server. As each peer is communicated to, you need to switch its state into active memory.
- Size—How much of a peer do you allow in the server? How big of an application? How do you constrain and manage it?
- Application—What is the application? Will all customers use it? Is there a value worth charging for?
Another possible solution that could have multiple peers is to interface to an existing server. The peers would act as a proxy view of the server so that the resources would be available over the P2P network. Nevertheless, this again can be solved with a distributed system of external peers that proxy the server. Resources can be added at will by adding more peers. A peer could also optionally use the server directly or use a proxy peer.
The whole idea of P2P computing is to distribute resources. By creating servers with multiple peers, you are going against JXTA and P2P philosophy. You are also burdening yourself with all the server problems that true P2P avoids.
Imagine true P2P solutions when faced with legacy servers or attitudes. Refactor your old server applications using JXTA when faced with costly or inadequate server technology.
A peer group is a way to group peers and to advertise specific services that are available to group members. You can create groups, join them, and of course resign from a group. There is also the ability to renew a membership in a group.
A group may need to limit membership for various reasons, such as secure communications between members, privacy, or there may need to be certain information that a user must supply before joining a group. There is an authentication protocol specifically designed to collect information and allow the group to determine if the information meets the requirements for membership.
The peer group provides context to use applications and to use the applications with other peers in the same group. For example, a peer group of jugglers would use a chat service in the juggling group. The effect would be to limit the chat to just those that joined the juggling group.
To further the juggling example, the group could authenticate users by validating a membership ID from a national juggling organization. Those without an ID would not be allowed to chat with the rest of the group, because they could not join the group.
Another way to look at groups is as a virtual private network (VPN). A VPN allows several computers to talk to each other without allowing the rest of the Internet to participate. VPNs include encryption so that the group conversation is not understandable to anyone who might eavesdrop. Peer groups also limit access to peers, and they can also use encrypted messages.
Membership to a peer group can take several forms. The two key models are local and remote membership services. A local membership service runs entirely on the peer that is applying for membership. All resources and ability to validate a user reside also on the same peer. So local membership services allow you to join without connecting to any other peer.
Remote membership requires accessing one or more peers in the group that you are joining. The idea is that peers that already belong to the group either have access to resources for validating a new member. Similarly, the set of peers in the group could query their users with the new member’s application to see if the members are willing to accept the new member.
The endpoint is the basic addressing method used by JXTA applications to communicate with each other. An endpoint is an address of a peer that implements a specific protocol of communication. A peer can have multiple endpoints and thus can be communicated with via different protocols.
Address as defined here is not necessarily a physical address. Endpoints allow the physical address to change. For example, in a DHCP-enabled ISP, the IP address of a computer that dials in, is going to be a random address each time.
A simple example of an endpoint is an IP address and port. By using these values, a stream could be opened to communicate to the target peer. However, JXTA places a layer on top of streams called pipes (discussed in the next section). Instead of connecting a stream to an address (represented by the endpoint), you connect a pipe to the endpoint. The beauty of endpoints and pipes is that you don’t care what the real address is or what the best protocol to use for a particular peer. In addition, there are other services used to route and even forward messages. Using the pipe and endpoint abstraction provides a lot of power and reduces the complexity of building a P2P application.
Because pipes connect via a communications protocol, the endpoint describes the protocol and the specific information used to connect to it. Therefore, the endpoint can describe an HTTP, TCP, BEEP, or other supported base communications protocol.
A peer can support one or more endpoints. By supporting more than one protocol, the peer can use the most effective method. In other words, if two peers are behind a firewall, they can communicate through their TCP endpoints. When these peers communicate to peers across the firewall, which traditionally filters everything but HTTP, they would use the HTTP protocol.
A pipe is a virtual connection between peers. Normally, we think of peer-to-peer communications as a single connection, but this is not always possible. The problem is that many peers cannot connect directly because of firewalls or other barriers. Pipes are intended as a layer over multiple communication protocols and to support relayed communications via gateway peers.
Pipes are a basic and important feature of JXTA. They create a very useful paradigm that allows peers to communicate in most network situation, despite firewalls or other barriers. Even if you do not know anything about a peer or where it is, you will to have a mechanism to communicate with the peer via a pipe.
Pipes are used as an abstraction to hide the fact that there may be other peers involved along with multiple connections. Pipes can also be implemented to be self-healing and reroute around an original peer. Self healing in important because a peer, unlike a server, is not meant to be available 24 hours a day and can be removed from the network at any time. The Java JXTA implementation has several flavors of pipe. As discussed, the JXTA protocols support and encourage different types of pipe. The following is a list of a few possible (currently not implemented) pipes that are either part of the Java implementation or possible additions:
- Uni-directional asynchronous—This is a pipe that is only used for communications that are in one direction. The pipe is asynchronous and messages may arrive out of order. This is the most basic type of pipe and should be implemented on most JXTA platforms.
- Synchronous request/response—All messages sent will receive a return message of acknowledgment. Messages arrive in the order that they were sent.
- Bulk transfer—Used to move large amounts of data.
- Streaming—Used to efficiently move data in a stream similar to that of audio, video, and other data streams, such as a stock market data feed.
- Bidirectional—A combination of two asynchronous pipes.
- Uni-directional synchronous—All messages sent will receive a return message of acknowledgment. Messages arrive in the order that they were sent.
- Unicast reliable secure pipe—All messages sent will receive a return message of acknowledgment and the data will be encrypted.
There are two different types of addressing for pipes:
- Point-to-point—Point-to-point pipes connect two different peers. Multiple other gateway peers can be used to create the connection.
- Propagate—Connects one peer to multiple destination peers. Propagate pipes are also called wire pipes because of the project that originally developed them. Propagate pipes can also have multiple peers involved in the connection, including those that are endpoints in the communication.
In the current platform, the uni-directional asynchronous, unicast reliable secure pipe, and bidirectional pipes are implemented. In addition, there is a secure version of a unicast and reliable secure pipe.
Endpoints and Pipes
JXTA is very different from a traditional network. Most network protocols have either no address (HTTP clients) or they have a fixed address where a URL or IP address is used to pinpoint the clients. JXTA abstracts the idea of a client address and calls it an endpoint.
A peer can have more than one endpoint. Peers can communicate over one or more protocols, such as TCP and HTTP, so there are usually multiple endpoints. This sounds strange at first because we usually deal with only one protocol in most applications. The reason JXTA uses multiple transport protocols is to allow a service to communicate with peers over the best method possible.
If you were behind a corporate firewall, you would use HTTP to communicate outside the firewall and TCP to talk to peers on the local LAN behind the firewall.
With multiple transport flexibility, you can use a specific protocol for a specific peer and thus the best speed and response. Behind the firewall, the speed and response is very good. Crossing the firewall, the response is poor. Overall, you are better off than if you only used HTTP that would have sacrificed efficiency behind the firewall.
An advertisement is an XML document that describes a JXTA message, peer, peer group, or service. Advertisements follow standards for encoding, tags, and content. The advertisement is used to exchange information about what is available in the JXTA network.
For an example of how this would work, imagine a peer that creates a peer group with the name Trekker Chat. The peer would publish the advertisement to the local JXTA network. This is done with an IP multicast. In other words, any peer in the sub-net will receive a copy of the advertisement. In addition the advertisement is sent to the rendezvous.
Peers use a special class of peers called rendezvous peers to discover advertisements from the rest of the network. Rendezvous peers (discussed in the next section), store advertisements and support searches. A peer can now request the peer group advertisement by searching for its name or other property. With the peer group advertisement, these client peers can then instantiate and join the Trekker Chat peer group by using the information contained in the XML. When they’re members, they can use the group context of services or locate peers that belong to the group.
Most of JXTA’s advertisements are encoded with UTF-8, which is an ASCII-preserving encoding method for Unicode (ISO 10646). Unicode could be used, but the advertisements do not use special language characters and foreign punctuation. Because UTF-8 is 8 bits and Unicode is 16 bits, the halving of the size of advertisements makes a lot of sense.
The only place you should find it necessary to use full Unicode is in the body of messages. Within messages, the encoding of the contents can be specified as Unicode or any other character set, including UTF-8.
Messaging in JXTA is done in two different ways. First is the standard way that would be expected with XML. The messages are packets that contain a payload of data formatted to follow XML standards.
The second type of message is a very economical binary message. Despite the desire to use XML for all JXTA messages, the reality is that there are many messages sent and received. The bulk of XML messages send in large volumes is very inefficient. Also, because messages are usually sent from application to application, it is simple to standardize on the contents of the message. The remainders of the protocols are still XML
The use of binary messages in an XML protocol may seem counterintuitive. The truth is that there are more advantages than just compactness. The first is that data can be compressed using standard techniques. Compression of data, such as text, can create a huge savings in time to transmit.
Another reason for binary data is that many messages are already binary. For example, a document-sharing program will most likely share binary documents. If you were transferring messages via XML, the data would need to be converted to XML.
Another reason for binary messages is encryption. Because the data needs to be converted to binary for encryption, moving straight to and from binary instead of XML makes sense.
JXTA has a wide selection of different identifiers. Identifiers range from large, unique identifiers to names and URLs. Identifiers are used like pointers of references. In the reference platform, identifiers are used for indexing, filenames, and searching.
A rendezvous is a peer that processes queries from other peers. The rendezvous can also delegate queries to other peers, which must also be a rendezvous. A key purpose of rendezvous is to facilitate searching of advertisements beyond a peer’s local network. Rendezvous usually have more resources than other peers and can store large amounts of information about the peers around it. In a peer network, information is scattered among peers and not stored entirely on any single machine, such as a server. Instead, there are rendezvous that distribute the storage of the advertisements.
Rendezvous peers can also act as relays of searches. The rendezvous peer can forward discovery requests to other rendezvous peers that receive their information from peers with whom they have exchanged advertisements. Each rendezvous will forward on a request if it does not have the information requested.
A typical search is illustrated in Figure 2.1. The remote search starts from Peer 1 which firsts queries local Peers 2 and 3 via IP Multicast. These Peers (2 and 3) are most likely on the local LAN and are quickly accessed. Next, if these Peers do not have the specified resource, a rendezvous peer is searched. If the rendezvous peer does not have the advertisement, successive rendezvous peers are searched. Note that besides the peers local to the query peer, only rendezvous peers are searched.
Figure 2.1: Rendezvous query routing.
IP Multicast is a one-to-many messaging protocol. IP Multicast is used to send one copy of data to a group address, reaching all recipients who are configured to receive it.
IP Multicast has two benefits over P2P applications. First, because multicast uses a group address instead of IP addresses, a peer sending a message can do so without knowledge of the listening peer’s address. The result is that all peers within the multicast network can now respond to the caller with information to the query and even their IP address for direct communication.
IP Multicast’s second benefit is the reduction of bandwidth. Because all peers can see a single message, there is no need to send a copy of the message to each peer. This is very important when sending large amounts of data to a group of peers.
A drawback to using multicasting is that some firewalls and routers block multicast messages. There is some support for sending multicast messages via Internet backbones between Internet providers, but it is often a service for which you must pay extra. There are other barriers to IP-Multicast. These can include personal firewalls and subnet routers. This is why JXTA supports more than just IP-Multicast.
In general, the multicast support available behind a firewall is sufficient for most P2P needs. You can take advantage of localized multicast support by sending duplicate messages for each network to a specific peer within the network for rebroadcast via multicasting to the local peers.
Only a rendezvous allows searching beyond a local network. A peer has the option of being a rendezvous, but it is not required. There is a side benefit of being a rendezvous—the peer will retain a cached copy of the results from other rendezvous of the result of cached answers to requests.
On the negative side of being a rendezvous, the peer will use more memory and higher bandwidth. Because of the possibly high number of requests and the resources consumed by a large database of advertisements, the case can be made for a dedicated rendezvous peer. In corporate installations, the rendezvous could also perform the duties of gateway and router for the corporate intranet. The effect would be similar to the use of a traditional router. Additional scaling could use a rendezvous in each of the corporation’s subnets.
The need for dedicated rendezvous peers depends on security and the scale of P2P applications used. The P2P network topology should be examined on a case-by-case basis and monitored regularly.
It is important to mention here that a P2P network becomes more efficient as services are duplicated among a large number of peers. However, there may be a point where additional rendezvous do not add to efficiency.
Rendezvous are used when a peer is searching for an advertisement or when other services use the rendezvous mechanism to route messages, so the need by a peer is not constant. A rendezvous connected to the Internet will be exposed to possibly thousands of peers. Within the bounds of a firewall-isolated network, having all peers configured as a rendezvous will probably not have a large affect caused by rendezvous tasks. Note that this observation may prove incorrect if there are many requests that have large search scopes.
Rendezvous are also used for application specific queries. In Chapter 9, “Synchronizing Data Between Peers,” peers use peers acting as rendezvous to propagate information about new appointments in a calendar as well as synchronizing an address book.
When considering any network topology or deciding if your peers should be a gateway, router, or rendezvous, be sure to check the current implementation for its efficiency and capabilities. Remember also that some applications may specifically use these services in unique ways. The JXTA platform will continue to evolve and should eventually cover most topologies or be configurable for many situations. But each environment is unique, so experimentation and monitoring of actual use may be the best way to configure your peers—especially in a large corporate environment.
A router in JXTA is any peer that supports the peer endpoint protocol. Not all peers need to implement the protocol because, like traditional network routers, you only need a few to support a large network. JXTA routers are very similar to a traditional router. The primary difference is that a P2P network is less stable and includes many addresses that are not static.
Figure 2.2 is an example of how a route is created. The request for a route starts at Peer 1 with the request for a route passed to available routers until the complete path to Peer 8 is built. Note that because a peer can be a gateway as well as a router, Peer 2 includes itself as a node in the route. Please understand that this is just conceptually how routers work, not how they are actually implemented. Routers can support caching or complex algorithms. For example, instead of the first router forwarding a request for the rest of the route, this router may already have a cached version of the route available.
Figure 2.2: Conceptual example of peer endpoint routers creating a route between Peer 1 and Peer 8.
A gateway is a peer that acts as a communications relay. Don’t confuse gateways with rendezvous. A gateway is used to relay messages between peers, not requests.
Gateways are like radio repeaters or a middleman between peers used to relay messages. Gateways are critical to connectivity because of firewalls, NAT devices, and network proxies. Gateways can store messages and wait for their intended recipient to collect the messages.
Gateways exist because the Internet is very messy. The mess is caused by the fact that we have all sorts of security and barriers that prevent a common way to communicate between peers. Another bit of this mess is the difference between protocols supported by peers. Some peers may use TCP, others may use HTTP. With wireless, we would need Wireless Application Protocol (WAP) as well. The gateway supports as many of these protocols as is possible so that it can act as a middleman between different types of protocols. JXTA started with support for TCP and HTTP, but other gateways are in development.
Gateways are key to getting around most of the security on the Internet. Firewalls, proxy servers, and NAT devices are the common security barriers. Figure 2.3 shows how the gateway Peer 2 is used to interface between Peer 1 and Peer 3. The gateway translates HTTP messages from peer 1 to TCP for delivery to Peer 3. When messages are sent from Peer 3, they are sent via TCP to Peer 2, which holds the message until Peer 1 makes an HTTP request to retrieve the data.
Figure 2.3: Example of gateway participation in a single pipe.
JXTA has started using the term relay to merge the terms rendezvous, router and gateway. Relay will also be used to include concepts like proxy, transcoding, and related “JXTA network helpers,” rather than proliferating a bunch of overlapping terms. It is also expected that there will be specialized peers or even commercial appliances that have just these functions, so a single name is more marketable. We will use the terms interchangeably for now, depending on the focus of discussion.
Why We Need Relays (Routers and Gateways)?
Although we have touched on the subjects, we need to specifically cover why relays are required for a P2P network. The following sections discuss each of the barriers to a P2P network. Each of these creates a need for us to abstract the network and create a virtual network where the P2P system provides routing and messaging via HTTP tunneling or to switch transport protocols.
Firewalls, which filter almost everything except HTTP, are most often found at larger companies, but they are also now found in homes that use special firewall routers. There are also personal firewalls, so called because they run on the user’s personal computer. Firewalls are often configured to filter almost everything except HTTP. HTTP only allows communications that are initiated by the client.
For example, when you are requesting a Web page, connecting to a Web server, sending the request, receiving the requested page, and then disconnecting. At no time does the Web server initiate a connection to the Web browser.
Because there is only one direction of communication that can be initiated, the gateway acts as a virtual agent that accepts messages for later delivery. Therefore, if a peer attempts to talk to a peer that can only initiate HTTP communications, the gateway holds the message until the HTTP peer contacts the gateway and asks for messages addressed to it.
NAT (Network Address Translator)
A Network Address Translator (NAT) device is just as disruptive as a firewall. Most wideband routers for cable and DSL use NAT.
NAT lets you use a single IP address for a whole network of computers. Because Internet providers charge by the unique IP address, many use a NAT to save money. The NAT sits between the public Internet and the a local area network (LAN) where it rewrites IP addresses and port numbers in IP headers on-the-fly so that the packets all appear to be with the public IP address of the NAT device instead of the actual source or destination. This causes multiple problems with applications that pass addresses and ports back and forth across the NAT. The NAT simply cannot detect and correct the message to reflect the mapped address. Essentially, this means that if you are behind a NAT, you will have trouble telling anyone what your address really is.
Many NATs, for security reasons, only allow incoming traffic from an outside address only if an outgoing packet has already been sent to that outside address. This is like a poor man’s firewall, because it prevents anyone from directly connecting to your computer without you first initiating communications. This is like a phone that cannot receive calls but will still let you call anyone.
A socket connection may be assigned to the same external address/port on subsequent connections. This means that you cannot be sure of a return path for messages. This makes it very difficult to create a two-way conversation.
The gateway gets around the NAT the same way it gets around a firewall. By using the HTTP protocol, the gateway on the other side of the NAT ensures that peers can communicate with the peer behind the NAT.
A proxy server is a device that sits between the Internet and a LAN. The proxy servers provide services like filtering, caching, and monitoring of traffic.
The result of having a network proxy is similar to a NAT. The proxy device can limit addresses as well as map them to others, such as NAT. Proxy devices can be as sophisticated as a firewall and limit certain types of communication. For example, a proxy service can prevent you from accessing a forbidden Web site. Some proxy servers can even detect viruses embedded in incoming e-mail before they ever reach your e-mail’s in-box.
The gateway can usually get around a proxy server by bridging the gap with HTTP. Some very sophisticated systems can be programmed to detect and prevent such traffic. Some companies only allow pure HTML to pass and discard all other types of data. In some cases, you may not be able to use JXTA applications without specific configuration and permission of the network administrator.
Many companies, and especially Internet service providers utilize Dynamic Host Configuration Protocol (DHCP). DHCP allocates IP addresses dynamically. The effect is that each time the DHCP server re-boots or a user’s computer re-boots, the IP address is changed. The address can also change if the IP address lease expires. The effect is that even a known address is a temporary address. Because of DHCP, even when you are behind a firewall, peers may still not have addresses on which you can depend. This makes it difficult when communicating across the firewall to peers on the other side.
The possibility of changing addresses is greatly improved by router peers. Router peers are able to create new routes between peers when addresses change.
Peers may also seem to disappear and reappear. This is a very common occurrence. Many computers are not connected to the Internet 24 hours a day. Many computers are still connected via dialup and are only on-line part of the day. We also have to consider wireless devices that are usually only on-line for very short periods. A laptop or a PDA can both appear and disappear as they are docked in and out of the network. In these cases, the peer may even seem to pop up in a different city in a completely different network topology! Because of the possibility of such changes, it is very important to be able to invalidate a route and reroute connections.
One of the problems with gateways is that they could significantly increase the time it takes for a message to be sent between two peers. If there are too many gateways, the total time for transmitting a message could be several minutes.
With the possibility of messages taking a very long time to transmit, there is a huge problem with managing a user’s expectation. An important number to think about here is 200 milliseconds, which is the amount of time between clicking a button and something happening that seems to be associated with the button. In other words, if an action occurs 200 milliseconds or less after you click a button, the action and its response appears to be simultaneous. If the application’s reaction to the button click takes longer than 200 milliseconds, your user is waiting. The longer a user waits, the more likely that the user is going to think that something has gone wrong. When the user believes that the application is not working, he or she could hit the button again, terminate the program to try again, or perform another action that you would like to avoid.
Any JXTA processing that is a result of a user’s input to the user interface should immediately display some kind of wait symbol or pop-up dialog as feedback. Any area of your software that has some type of JXTA network communications will most likely need to be in a thread separating it from the user interface. In addition, while waiting on the JXTA network, some type of user feedback, such as a wait dialog or a status display, is a necessity. Applications will be more complex, and you will need much more code to make them thread safe, but the effort is required to make your application acceptable.
JXTA protocols are used to help peers discover each other, interact, and manage P2P applications. The protocols are not applications in themselves and require much more code to create something useful. The protocols hide a lot of detail, which makes writing JXTA applications much easier than developing a P2P applications from scratch.
JXTA defines its protocols in the JXTA Protocols Specification. The specification describes how peers communicate and interact; it does not attempt to describe the specifics of implementation or how to write a peer-to-peer application. In this section, we are going just give you an overview of the protocols and discuss related issues.
The following is a list of the JXTA protocols. We have included their acronyms, but we use acronyms rarely in the rest of this chapter:
- Peer Discovery Protocol (PDP)—Allows a peer to discover other peer advertisements (peer, group, service, or pipe). The discovery protocol is the searching mechanism used to locate information. The protocol can find peers, peer groups, and all other published advertisements. The advertisements are mapped to peers, groups, and other objects, such as pipes.
Queries are made by specifying an advertisement type (peer, group, or advertisement), an XML tag name within the advertisement, and the string to match against the data represented by the XML tag.
- Peer Resolver Protocol (PRP)—Allows a peer to send a search query to another peer. The resolver protocol is a basic communications protocol that follows a request/response format. To use the protocol, you supply a peer to query and a request message containing XML that would be understood by the targeted peer. The result is a response message.
The resolver is used to support communications in the JXTA protocols like the router and the discovery protocols. For example, the protocol is used by the discovery protocol to send queries that represent searches for advertisements.
The resolver also allows for the propagation of queries. For example, if a peer receives a query and does not know the answer, the resolver sends the query to other peers. This is an interesting feature, especially because the originating peer does not need to have any knowledge of a peer that may actually have the result to the query.
- Peer Information Protocol (PIP)—Allows a peer to learn about the status of another peer. The information protocol is used partially like ping and partially to obtain basic information about a peer’s status. The body of a PIP message is free-formed, allowing for querying of peer-specific information. In addition, this capability can be extended to provide a control capability.
- Peer Membership Protocol (PMP)—Allows a peer to join or leave a peer group. The protocol also supports the authentication and authorization of peers into peer groups. The protocol has three key advertisements for authorization, and the credential. The credential created in this protocol will used as proof that the peer is a valid member of the group.
- Pipe Binding Protocol (PBP)—Is used to create the physical pipe endpoint to a physical peer. It is used to create a communications path between one or more peers. The protocol is primarily concerned with connecting peers via the route(s) supplied by the peer endpoint protocol.
- Rendezvous Protocol (RVP)—The Rendezvous Protocol is responsible for propagating messages within JXTA groups. The Rendezvous Protocol defines a base protocol for peers to send and receive messages within the group of peers and to control how messages are propagated.
- Peer Endpoint Protocol (PEP)—Is used to create routes to route messages to another peer. The protocol uses gateways between peers to create a path that consists of one or more of the pipe protocols suitable for creating a pipe. The pipe binding protocol uses the list of peers to create the routes between peers.
One of the more significant problems is that traditional routers and DNS servers fail because of firewalls, proxy servers, and NAT devices. This protocol searches for gateways that allow the barriers, such as firewalls and others, to be traversed.
This protocol also helps when the communicating peers don’t support each other’s protocols. For example, if you are connecting peer-A that supports TCP and peer-B that only supports HTTP, the endpoint protocol would choose either one gateway that could make the translation or multiple gateways with multiple but compatible protocols.
We can also describe these protocols in terms of what they provide to a JXTA application. The next list is very basic, but probably is the best way to look at what the protocols really do.
- Peer Discovery—Resource search
- Peer Resolver—Generic query service
- Peer Information—Monitoring
- Peer Membership—Security
- Pipe Binding—Addressable messaging
- Rendezvous—Propagation messaging
- Peer Endpoint—Routing
In the remainder of this chapter, we will describe these concepts further. In the following, we relate the concepts of peers, groups, and how the protocols are associated. In Chapter 3, we will cover the concepts again, but in terms of the Java implementation and the API.
Peers and Groups
The two primary concepts to understand about JXTA are peers and groups. Because peers and groups are a little complicated, we will discuss each one in detail.
As discussed earlier in the chapter, peers are individual nodes on the JXTA network. The peer is similar to a computer on a network, except that you can run multiple peers on a single machine. Peers can be a standard PC, a PDA, an appliance, or even a super computer.
A Peer Is Not a User
The concept of the peer should not be confused with the concept of a user. A peer is a node on the network. Think of a normal computer on the Internet; you should not assume that a single person uses the computer. The computer could be shared by a family or be a publicly used device, such as an Internet kiosk. You also should not assume that a peer node is the only place a user will access the P2P network. The user can access the network from home, work, or through various devices.
In your design of services and applications, be very careful to avoid linking the user to a peer, either permanently or for long periods. Sometimes, you can link a user to a peer, but always be able to log the user off and log in another.
One of the many things you need to manage in a P2P application is identity. The peer is associated with the user in many respects, so for now we will discuss this in terms of a peer. You should create an authentication system where multiple peers could be aggregated as a single user.
The types of things you should manage are authenticating the peer’s rights to use services. The identity of the peer in JXTA is a credential. The credential is used throughout the system to ensure that certain operations have the correct permissions. The credential is officially created when a peer joins a group. The credential can also simply be some type of token created ahead of time and presented as part of the joining process. The group recognizes the credential during the authentication process when joining the group.
Why Use Groups?
P2P networks have several key differences from traditional networks, the most important being the ability to control what peers can do. The following are some of the problems:
- Too many peers connecting to one peer for a resource.
- Peers that use resources but do not contribute to resources.
- Certain resources should only be accessible to a set group of individuals.
- Hackers of the general network who are seeking to damage or take over the network.
In P2P networks, it’s very difficult to control behavior of rogue peers. There are many different types of mischief, including abuse of other peer’s resources. There is also the obvious need to limit access to applications or resources for security or privacy reasons.
To begin to understand how these problems can be overcome, let’s look at a use case diagram of a simplistic P2P system. In Figure 2.4, users interact with different instances of a service-A, which collaborates with other services to access specific resources attached to specific instances. In this sort of P2P network, the services are left with the responsibility of security. Each service on each peer must act as a gatekeeper to the data controlled by the peer.
Figure 2.4: Functional view of the peer service use case.
The drawing in Figure 2.5 is representative of how JXTA works. In JXTA, the peer group is a virtual gatekeeper. The service, and thus the service data, resides in the context of the group. The group code is replicated on each platform, but we are showing it as a single entity accessed by all of the group members. The services are accessed through the group, and the services have a context of the group.
The key difference here is that the group contains the security features while the services are only concerned with verifying that other peers are valid members. Credentials created by the group and given to the peers (not shown) will be validated by the group context. Figure 2.5 shows how groups are seen programmatically in JXTA. As can be seen, users interact with a service controlled by the group. The group is ensuring a single point of control, despite the fact that the service and data is distributed.
Figure 2.5: Conceptual view of group-based service.
By using groups, you have at least a chance of controlling peers with a common authentication scheme. You also have a platform to disseminate information to a limited set of group members. For example, you could send a message to other peers that a rogue peer should be ignored.
Given the discussion so far, you may be confused as to what a JXTA application is. We have talked a great deal about how an application would do its work, but not where the code for the application resides.
To begin with, the general notion of an application has not changed. The key difference is that your JXTA application begins with starting the JXTA platform by accessing the world group. The world group is a group that is accessible to all peers. The world group is used to locate any peer or information that is available to all peers.
After the platform is started, your peer is a member of the default world group. From this point, you could begin your application with the world group and use all of the default services in the world group.
Group membership is probably one of the more important service protocols. Membership has two key features—authentication and credentialing. Authentication is the gatekeeper for the group, while credentialing is a token that ensures that authentication occurred. Both authentication and credentialing could be complex or simple, depending on how rigorous you need to be in your group.
Authentication is a multi-step process where the group requests that the peer supply information to join the group. The information supplied is then validated against the group’s requirements for membership. The most obvious validation would be a user ID and password. Less restrictive systems may not ask for information or may be just a simple questionnaire. In the most restrictive systems, the authenticator may ask for an encrypted digital signature.
Credentials can also have various contents. Because credentials are passed around, they are usually fairly small to reduce overhead. In the least restrictive groups, the credential will just be a simple token. In groups that are paranoid about user identity, the credential would be a wrapper for encrypted digital signatures.
Peer Group Services
Peer groups are a context for services that interoperate in the group’s domain of users. The peer group provides a set of services called peer group services that implement the JXTA protocols to supply the group with the necessary functionality. These services are not required, but most groups will probably have these services available for use by other services and applications. Groups can contain any set of services, and different groups can contain the same services of other groups.
Services are always associated with a group. You cannot have access to a service unless you are a member of the group. The services that a group supports are listed in the group advertisement.
The importance of the associating services to a group is to limit their scope. As a rule, services should not interact with peers not in their group. One reason is a matter of respect for peers that are not a part of the same group. There is also the practicality that there may be no reason to interact with peers outside of the group because they will not have the resources the service requires.
It is possible to write a service that will operate across groups. Such a service is unlikely because of the access service. The access will forbid any messages that are not properly marked as belonging to the group. Any service that goes across groups would need to have the cooperating access services.
If you need to interact with multiple groups, it is simpler to have an application that joins each group. There is no limit on how many groups a peer may join.
Not all groups have the same advertisements, but it is expected that all groups support a set of standardized services that represent the core protocols. It is possible that none of these services are included or a completely different set of services would be provided. Without these core services, it would be difficult to interact with other peers. However, you could imagine a peer that uses a custom gateway that provides the functionality without requiring it on the peer itself. In addition to these core services, the creator of the group can add additional services. There are no specific requirements for these services. However, the services are expected to only work within the bounds of the group. If you use the core services for discovery and communication, limiting the scope to the group is automatic. The core services are described in the following sections.
The discovery service provides access to Peer Discovery Protocol in the context of the group. It searches for peer group resources (peers, peer groups, pipes, and services). The search usually only searches within the group that contains this discovery service reference, so if a group is created and you use its discovery service, only advertisements published in that group will be found. Note, however, that this also depends on the implementation of the group that may expand the search scope to parent, sibling, or sister groups.
Some groups may inherit the search scope of the parent group. By default, the world group has access to all Peer advertisements and others created in its context. The default behavior of other groups is to search only in their scope.
The membership service provides access to a group-specific version of the Peer Membership Protocol. It is used as a gatekeeper to membership in the group. Peers wanting to join the group must fulfill the requirements of this service. The model is that of a membership application form where a document is submitted to the peer to be filled in and submitted for approval. If the peer is approved, the peer is considered a member of the group and is issued a credential that is used as proof of membership during communications. The membership service can extend the model from an application to external validation (such as a server that validates the user’s initial credential) or by querying other peers or a manager peer for final approval (voting). We will cover group membership in more detail in Chapter 6, “Working with Groups.”
The access service is part of the membership service and is used to ensure that the peers are actually valid members of the group. This service uses the credential created when the peer joined the group. A peer receiving a request provides the requesting peer’s credentials and information about the request being made to the access service, and the service determines if the context and credentials are correct; if so, access is permitted.
Peer Authentication Service
The authentication service uses credentials created by the membership protocol to verify that that messages are from a valid member of the group. The concept is that the application examines a credential for certain operations as needed to ensure that communications are with valid peers.
Authentication uses the credential as a standalone packet of information that is either self-authenticating or can be verified with other information the current peer obtained from another source.
The peer authentication service is not currently implemented in the Java JXTA platform.
The pipe service implements Pipe Binding Protocol. The pipe service is used to manage and create pipe connections between the different peer group members.
The resolver service implements the resolver protocol. The resolver service distributes queries to other resolver services running on peers within the group. The resolver also listens for the answers to these requests. We discuss this subject in more detail later in the chapter, in the “Resolver” section. We also use the resolver directly in Chapter 9, “Synchronizing Data Between Peers.”
The monitoring service is used to allow a peer to monitor other group members of the peer group. The specification of what is monitored is left to the implementer. Monitoring can be used to collect data on peers to ensure they are following the group’s rules for behavior or just to gather simple statistics.
Monitoring of peers is mentioned in the specification, but few people have implemented the concept. There also appears to be no API harness to use as a base. The implementation would need to be a service that you create and make a part of your group.
The reasons for having a monitoring service are many. The following are a few:
- Keep a log of peer activities (downloads, contributions, and so on) that are sent to other peers. This relates to the next item.
- You could manage a peer’s ability to use the group. This is similar to Gnutella that prevents a peer from downloading unless they also share a minimum of their content. This can be expanded to include other information, such as up-time and other statistics that trigger certain rights. The opposite is that other peers receive these statistics before they interact with the peer, so that they can decide if they want to interact with the peer. This can be automated or just presented to the wizard behind the curtain.
- Management of the user access is also important. In the specification, there is no mention of a revocation of a group membership. There is the idea of expiration and renewal. The problem is that you may not want to wait for expiration and want to remove a user early. This relates back to using a credential, which is a part of the specification and can be used to notice when a user is no longer valid.
- Managing issues like those that cause problems in JXTA, including abuse of resources, falsification of identity, hacking/hijacking of the group for other purposes, and denial of service attacks against the group or some of its peers.
Note that some of these core services, such as discovery and membership, implement JXTA protocols. Others, such as the monitoring service, are not associated with a protocol, but are useful in a group context.
Core services are not necessarily specific implementations. Core services for the group can provide specific behavior for the group. For example, the membership service is likely a specific implementation.
Core Services Are Optional
Core services, besides being customizable, may not even be supplied. For example, the monitoring service may not be provided if there is no reason for monitoring. Also, the discovery service may not be required if the peer is already populated with all the advertisements it needs.
The only service that is most likely to be supplied is the membership service. The reason is that when a peer joins the group, the membership service is used. If a group does not need membership, you should use the Null membership implementation that allows the join functionality to operate but does not impose membership requirements.
Groups as Applications
One aspect of groups that may seem odd at first is thinking of groups as applications. A group application is not a real stretch of imagination and actually provides a lot of utility. The simple fact is that an object needs to exist to represent the group. Because there is an object, it would need methods to create, destroy, and manage resources. As mentioned, a group also has other services that need to be started and stopped. For all of these reasons, associating groups with applications is reasonable.
However, groups do not need to be associated with applications in a programmatic way. Groups can simply be used as a context to manage the groups of peers or groups of information. You do not need to add services to your groups and simply use the default services. For example, you could have an application such as SETI@Home implemented as a JXTA group with services for membership, communication, and reporting results. These would begin operation as soon as the group was joined and the default application in the group started. We will cover more of this in Chapter 3, when we discuss the Java implementation of groups.
Finding Information about the JXTA Network
When using the peer discovery protocol, there are three scoping parameters. These include the advertisement type (peer, peer group, or advertisement), a tag name to search with the contents to match, and a limit on how many advertisements for which to search. Only the first two are important to us here. The first scoping parameter specifying the type is useful to limit what you are looking for to just one of three different types of advertisements. The second, which allows you to specify a name and value, is then used to search each advertisement for matching XML tag and value.
The important qualifier is the name of the XML tag. This lets you choose a specific element of an advertisement, such as the name tag or an ID tag. This allows you to look up, for example, a named peer, a named group, or any other advertisement based on some tag name and its contents. Because the * wildcard is supported in the Java implementation, you can do more creative searches.
Passing Extra Data in Advertisements
It should be noted that many of the advertisements in JXTA can be expanded with additional XML tags. In some cases, these areas are clearly marked, such as the param section of the peer group advertisement. Be careful where you do put data and what type of tags you are using, because the messages may fail a syntax check. This version on JXTA does not support XML syntax checking but does have various places where unexpected XML could cause problems. You should only add data where allowed or use queries or pipes to pass information.
Adding data to advertisements that are outside of the protocol specification should only be done when you are implementing a variation on a protocol. For example, you could create a new transport type and add it to the group membership advertisement’s TransportAdvertisement tag.
Caching and Aging of Advertisements
Advertisements are usually cached. Caching is not required by JXTA, but it is very useful and efficient to do so. Aging is a way to set an expiration time when an advertisement should be considered too old to be useful. Some advertisements can last a very long time, like peers, and others that are more volatile, like pipes.
There are two different ages—one local set by default to 365 days and one remote age set to 2 hours. The assumption would be that if the peer created the advertisement, it has value and should have a long lifetime. Advertisements coming from remote systems are suspect and should expire much sooner. Because advertisements are renewed, the shorter lifetime is moot unless the advertisement was really temporary or its peer unstable.
Advertisements are the language of JXTA. All of the information about peers, groups, services, and other JXTA constructs are defined by an advertisement. The following is a quick list of the main advertisement types:
- Module Class Advertisement (MCA)—Defines the specific version of a module.
- Module Specification Advertisement (MSA)—Defines the module with a cross platform definition that includes behavior.
- Module Implementation Advertisement (MIA)—Specific instance of a module on a platform.
- PipeAdvertisement—Defines. See PipeAdvertisement; a pipe available in a group or at a peer.
- PeerGroupAdvertisement (PGA)—Defines the peer group. The group also defines the services, endpoints and other information.
- PeerAdvertisement (PA)—The peer advertisement defines the peer.
- EndpointAdvertisement—The endpoint advertisement defines a communications protocol and the termination.
We’ll discuss these in more detail in the next section, Details of the Advertisement Types.”
There are really only three classifications of advertisements. These are peers, peer groups, and everything else. It is difficult to say why these are the highest level, but the cache management system in the Java implementation uses these types to separate the advertisements into three separate directories.
Details of the Advertisement Types
Now we will look at each of the advertisements that JXTA uses in detail and talk about what they mean. We will also show some XML so that you will know how to recognize advertisements when debugging.
Peer Group Advertisement
The peer group advertisement is used to define both an identification of a group and the services of that group. Peer group advertisements have the following information:
- Name—Name of the group.
- Description (Desc)—Description of the group.
- PeerGroup ID (GID)—An ID that is associated with this instance of this group.
- PeerGroup Specification ID (MSID)—A Module Spec ID that this group uses. The ID is used to locate a module that references the services this group uses.
- Service (Svc)—Optional list of elements that associate a group service, denoted by its Class ID (the value of an MCID element), and parameters via Parm elements.
The following is an example of an XML PeerGroupAdvertisement for a peer group created in Chapter 9:<?xml version="1.0"?> <!DOCTYPE jxta:PGA> <jxta:PGA xmlns:jxta="http://jxta.org"> <GID> urn:jxta:uuid-AAA122616461AAAAAAA124615032503302 </GID> <MSID> urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE000000010306 </MSID> <Name> JPDA_ROOT_GROUP </Name> <Desc> Root application group </Desc> </jxta:PGA>
A peer advertisement is almost identical to a peer group advertisement. The key difference, of course, is its type.
- Name—Name of the peer.
- Description (Desc)—Description of the peer.
- PeerGroup ID (PID)—An ID that is associated with this peer instance.
- Debug Flag (Dbg)—Optional tag used for debugging.
- Service (Svc)—Optional list of elements that associate a group service, denoted by its Class ID (the value of an MCID element), and parameters via Parm elements. In most implementations, this will hold data that details information used to converse with the peer.
The following is an example of XML PeerAdvertisement. The service defined in this example defines the parameters for the MCID that references the default implementation for a peer. The data includes the endpoints for TCP, the group, and an HTTP ID used by an HTTP gateway. The second MCID refers to the implementation of secure pipes and defines a certificate:<?xml version="1.0"?> <!DOCTYPE jxta:PA> <jxta:PA xmlns:jxta="http://jxta.org"> <PID> urn:jxta:uuid-59616261646162614A7874615032503356 CFE39F036E4038ABE1801D40772DC803 </PID> <GID> urn:jxta:jxta-NetGroup </GID> <Name> Super Chicken </Name> <Svc> <MCID> urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE0000000805 </MCID> <Parm> <Addr> tcp://18.104.22.168:9701/ </Addr> <Addr> jxtatls://uuid-59616261646162614A7874615032503356CFE39F036E4038A BE1801D40772DC803/TlsTransport/jxta-WorldGroup </Addr> <Addr> jxta://uuid-59616261646162614A787461503250 3356CFE39F036E4038ABE1801D40772DC803/ </Addr> <Addr> http://JxtaHttpClientuuid-5961626164616261 4A7874615032503356CFE39F036E4038ABE1801D40772DC803/ </Addr> </Parm> </Svc> <Svc> <MCID> urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE0000000105 </MCID> <Parm> <RootCert> MIICODCCAaGgAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMRUwEwYDVQQKEwx3d3cu anh0YS5vcmcxCzAJBgNVBAcTAlNGMQswCQYDVQQGEwJVUzESMBAGA1UEAxMJU2th bmRhLUNBMR0wGwYDVQQLExRDMkEwNDlGMDBBRjc4NkEyOUI0RTAeFw0wMTEyMjEw NDIzNTlaFw0xMTEyMjEwNDIzNTlaMGQxFTATBgNVBAoTDHd3dy5qeHRhLm9yZzEL MAkGA1UEBxMCU0YxCzAJBgNaBAYTAlVTMRIwEAYDVQQDEwlTa2FuZGEtQ0ExHTAb BgNVBAsTFEMyQTA0OUYwMEFGNzg2QTI5QjRFMIGbMAsGCSqGSIb3DQEBAQOBiwAw gYcCgYEArRbPEHoij/J0PYaI/b7xPmj1MsVX5BmrJqNUjsaEroJewTJ3ffDAyNOl WWC/lTGD8maUhlK7vycVozboaaelOJSDjkZ/gDBYglwDrciFsMsKTcwdYdp6x3/s PmUwAHDu8AvPvpyq/2UNNCMxPL9G+OfVnBAxG5TdNvnpSVZXX8MCAREwDQYJKoZI hvcNAQEFBQADgYEAGRmbIRoq0EQQEfg3jIdc/WIChIpYCIZq06VLkESntqBCCnfN z/YWFMeJRwXGZmZqG321wMVpQytRMUr2ewnVXJjvsVZiH1erd1bgUzKoIpcJy6Bd X+/cuiFUWxkQu+GTNcjt1ytjGbpNy/kUxg7bPTOXU55c1XDzN/+ASMLqxo8= </RootCert> </Parm> </Svc> </jxta:PA>
Modules are definitions of services and applications available on a peer or in a peer group. Modules are used to define the code to be executed. To ensure that different peers written with different languages, versions, and operating systems, modules are defined with three different XML advertisements:
- Module Class—Defines the specific version of a module.
- Module Specification—Defines the module with a cross platform definition that includes behavior.
- Module Implementation—Specific instance of a module on a platform.
Each advertisement is used to narrow the final implementation used by the peer. However, only the respective IDs may be available and no true advertisement available on the general network. The reason is that some modules are not public or they do not have different versions or implementations. Instead, the advertisements are internal to the peer and only referenced by their identifiers as needed. The following three sections define the detail of the different module advertisement types.
Module Class Advertisement
A Module Class advertisement defines behavior. Peer groups, peer, and other advertisements reference a module class ID that is defined by the module class advertisement. The advertisement has the following parameters:
- Module class ID (MCID)—Unique identifier used to reference the module class.
- Name—Name of the module. Used for searching and identification. Not guaranteed to be unique.
- Description (Desc)—Description used for searching and identification.
The following is a sample advertisement. This is the module class advertisement for the EX1 advertisement:<?xml version="1.0"?> <!DOCTYPE jxta:MCA> <jxta:MCA xmlns:jxta="http://jxta.org"> <MCID> urn:jxta:uuid-2584FEB44D3B40E9A16A8419C9ABE09F05 </MCID> <Name> JXTAMOD:JXTA-EX1 </Name> <Desc> Tutorial example to use JXTA module advertisement Framework </Desc> </jxta:MCA>
Module Specification Advertisement (Module)
A Module Specification Advertisement is the specification of a module. The advertisement contains information about the implementation referred to by a module specification ID. Because the code for a module is usually part of the peer application, there is no need to publish the advertisement for each ID, but it is a good practice to document the module via the advertisement. Each module has the following tags:
- Module spec ID (MSID)—An ID that specifically defines this module.
Compatibility statement—An XML specification used to define the compatibility of the code to a language and version.
- Name—Name of the specification.
- Description(Desc)—Description of the specification used for searching and identification.
- Creator (Crtr)—Creator of the specification.
- Specificaton URI document (SURI)—URI of a specification document.
- Version (Vers)—Version of this specification.
- Parameters (Parm)—List of parameters to be used by the implementation.
- Proxy—ModuleSpecID of a proxy module if one exists.
- Authenticator (Auth)—ModuleSpecID of an authenticator module if required.
The following is an example of the XML for the module specification for the EX1 example. Note that in addition to its standard tags, there is a pipe advertisement used to communicate to the module. This is done as a convenience, so that the user of the code does not need to look for an extra pipe advertisement:<?xml version="1.0"?> <!DOCTYPE jxta:MSA> <jxta:MSA xmlns:jxta="http://jxta.org"> <MSID> urn:jxta:uuid-88A7B34E2B354A75A181B34E6058D3DA0F 230D7557A24F159F80ABA479BC0C3B06 </MSID> <Name> JXTASPEC:JXTA-EX1 </Name> <Crtr> sun.com </Crtr> <SURI> http://www.jxta.org/Ex1 </SURI> <Vers> Version 1.0 </Vers> <jxta:PipeAdvertisement> <Id> urn:jxta:uuid-9CCCDF5AD8154D3D87A391210404E59 BE4B888209A2241A4A162A10916074A9504 </Id> <Type> JxtaUnicast </Type> <Name> JXTA-EX1 </Name> </jxta:PipeAdvertisement> </jxta:MSA>
Module Implementation Advertisement
The Module Implementation advertisement is the final link in the chain to define a module. The advertisement defines specific references to a specific language representation on a peer. This advertisement is used to launch the code.
- Name—Optional name associated with the module.
- Description (Desc)—Optional string used to describe and allow for searching of key words to locate a module.
- ModuleSpecID (MSID)—ID that uniquely identifies the specification being implemented.
- Compatibility (Comp)—An element that describes the execution environment. For Java this would be the JVM version.
- Package URI (PURI)—Optional URI used to download the code of this implementation (not implemented in version 1.0).
- Code—Contains a reference used to load and execute the code of this implementation. For a Java module, this is a fully-qualified classname.
- Parameter (Parm)—Arbitrary parameters to be interpreted by the implementation’s code.
- Provider (Prov)—Provider of the implementation.
The following is the module implementation for the standard peer group. Note that this implementation contains further implementation advertisements in the param tag. Also note that the last entry is the shell application. The shell is defined this way as the default application of the peer group. If the peer group is started after it is initialized, the code in the application tag is executed:<?xml version="1.0"?> <!DOCTYPE jxta:MIA> <jxta:MIA xmlns:jxta="http://jxta.org"> <MSID> urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE000000010306 </MSID> <Comp> <Efmt> JDK1.4 </Efmt> <Bind> V1.0 Ref Impl </Bind> </Comp> <Code> net.jxta.impl.peergroup.StdPeerGroup </Code> <PURI> http://www.jxta.org/download/jxta.jar </PURI> <Prov> sun.com </Prov> <Desc> General Purpose Peer Group Implementation </Desc> <Parm> <Svc> <jxta:MIA> <MSID> urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE000000060106</MSID> <Comp> <Efmt> JDK1.4 </Efmt> <Bind> V1.0 Ref Impl </Bind> </Comp> <Code> net.jxta.impl.rendezvous.RendezVousServiceImpl </Code> <PURI> http://www.jxta.org/download/jxta.jar </PURI> <Prov> sun.com </Prov> <Desc> Reference Implementation of the Rendezvous service </Desc> </jxta:MIA> </Svc> <Svc> <jxta:MIA> <MSID> urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE000000030106 </MSID> <Comp> <Efmt> JDK1.4 </Efmt> <Bind> V1.0 Ref Impl </Bind> </Comp> <Code> net.jxta.impl.discovery.DiscoveryServiceImpl </Code> <PURI> http://www.jxta.org/download/jxta.jar </PURI> <Prov> sun.com </Prov> <Desc> Reference Implementation of the DiscoveryService service </Desc> </jxta:MIA> </Svc> <Svc> <jxta:MIA> <MSID> urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE000000050106 </MSID> <Comp> <Efmt> JDK1.4 </Efmt> <Bind> V1.0 Ref Impl </Bind> </Comp> <Code> net.jxta.impl.membership.NullMembershipService </Code> <PURI> http://www.jxta.org/download/jxta.jar </PURI> <Prov> sun.com </Prov> <Desc> Reference Implementation of the MembershipService service </Desc> </jxta:MIA> </Svc> <Svc> <jxta:MIA> <MSID> urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE000000070106 </MSID> <Comp> <Efmt> JDK1.4 </Efmt> <Bind> V1.0 Ref Impl </Bind> </Comp> <Code> net.jxta.impl.peer.PeerInfoServiceImpl </Code> <PURI> http://www.jxta.org/download/jxta.jar </PURI> <Prov> sun.com </Prov> <Desc> Reference Implementation of the Peerinfo service </Desc> </jxta:MIA> </Svc> <Svc> <jxta:MIA> <MSID> urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE000000020106 </MSID> <Comp> <Efmt> JDK1.4 </Efmt> <Bind> V1.0 Ref Impl </Bind> </Comp> <Code> net.jxta.impl.resolver.ResolverServiceImpl </Code> <PURI> http://www.jxta.org/download/jxta.jar </PURI> <Prov> sun.com </Prov> <Desc> Reference Implementation of the ResolverService service </Desc> </jxta:MIA> </Svc> <Svc> <jxta:MIA> <MSID> urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE000000040106 </MSID> <Comp> <Efmt> JDK1.4 </Efmt> <Bind> V1.0 Ref Impl </Bind> </Comp> <Code> net.jxta.impl.pipe.PipeServiceImpl </Code> <PURI> http://www.jxta.org/download/jxta.jar </PURI> <Prov> sun.com </Prov> <Desc> Reference Implementation of the PipeService service </Desc> </jxta:MIA> </Svc> <App> <jxta:MIA> <MSID> urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE0000000C0206 </MSID> <Comp> <Efmt> JDK1.4 </Efmt> <Bind> V1.0 Ref Impl </Bind> </Comp> <Code> net.jxta.impl.shell.bin.Shell.Shell </Code> <PURI> http://www.jxta.org/download/jxta.jar </PURI> <Prov> sun.com </Prov> <Desc> JXTA Shell reference implementation </Desc> </jxta:MIA> </App> </Parm> </jxta:MIA>
Pipe advertisements describe the type of pipe. Pipe advertisements are rather simplistic. They only have a name, ID, and type. As we have discussed, there are several different types of pipe. The specific pipe type is listed in the Type tag.
Pipes contain the following tags:
- Name—Name of the pipe.
- Id—The ID of the pipe.
- Type—The type of the pipe. Type is related to a protocol and therefore to endpoints on a peer. Types are UnicastType, UnicastSecureType, and PropagateType.
The following is an example of an XML pipe advertisement. This pipe is a unicast pipe:<?xml version="1.0"?> <!DOCTYPE jxta:PipeAdvertisement> <jxta:PipeAdvertisement xmlns:jxta="http://jxta.org"> <Id> urn:jxta:uuid-59616261646162614E50472050325033A10C F46E7B7041B48C3EBF32A5DA2A4404 </Id> <Type> JxtaUnicast </Type> <Name> frodo.replyTo </Name> </jxta:PipeAdvertisement>
Endpoint Router Messages
The router protocol uses query and response messages to discover routes. The query message supplies the peer ID of the destination. The ID of the origin is assumed that of the source. This message is sent from a peer to a peer, which implements the peer endpoint protocol. The XML endpoint router query message schema is as follows:<xs:element name="EndpointRouterQuery" type="jxta:EndpointRouterQuery"/> <xs:complexType name="EndpointRouterQuery"> <xs:element name="Credential" type="xs:anyType" minOccurs="0"/> <xs:element name="Dest" type="xs:anyURI"/> <xs:element name="cached" type="xs:string"/> </xs:complexType>
The router answer message contains the information about the route that was located by the router or a router it collaborated with to create the answer.
The actual route is a list of peers that are all gateways, except the final destination that is not required to be a gateway:<xs:element name="EndpointRouterAnswer" type="jxta:EndpointRouterAnswer"/> <xs:complexType name="EndpointRouterAnswer"> <xs:element name="Credential" type="xs:anyType" minOccurs="0"/> <xs:element name="Dest" type="xs:anyURI"/> <xs:element name="RoutingPeer" type="xs:anyURI"/> <xs:element name="RoutingPeerAdv" type="xs:string"/> <xs:element name="Gateway" type="xs:complexType"/> </xs:complexType>
Message advertisements are used for the various messaging protocols, as well as for user defined messages. There are two different types of messages—XML and binary.
XML messages are used for transport mechanisms that only support text or as a general way to send a message. Because messages are seen as the most used type of data that is transported between peers, the binary message is offered in most cases because it is much more efficient.
The XML message format consists of a message tag that encapsulate the data of the message. Each element has a name, a mime type, and an optional encoding parameter. By changing the mime type and the encoding, you can place any supported data type between the enclosing element tags that is valid XML. For data that is not XML, the < character is replaced with the string <, and & symbols are replaced with & as equivalent. The following is an example of an XML message:<!DOCTYPE Message> <Message version="0"> <Element name="jxta:SourceAddress" mime_type="text/plain"> tcp://123.456.205.212 </Element> <Element name="stuff" encoding="base64" mime_type=" application/octet-stream"> AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygp KissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUV JTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eH l6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6Choq OkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsc= </Element> </Message>
Binary messages are compact packets used to send information with as compact a data stream as possible. Two-byte lengths are sent with the high-order byte first. All strings start with a two-byte length, followed by the UTF8 string value. The message format is specified by using ABNF (see IETF RFC 2234 at http://ietf.org/rfc/rfc2234.txt). The format of the binary message is defined by Tables 2.1 and 2.2.
Table 2.1 Binary Message Format
Section Description "jxmg" Start of the message. Version One byte. Must be 0 for the 1.0 binary format. Namespaces See Namespaces. element_count Two bytes designating the number of elements to follow.
Table 2.2 Message Element
Section Description "jxel" Element signature. namespaceid One byte that designates the name space. Flags Indicates which parts follow 0×00 if type is not present and 0×01 if type is present. simple_name Name of this element. If the namespace ID is 0, the simple name is the name. Otherwise concatenate the namespace name designated by the ID with a colon (:) and the simple name. The next byte is the flags byte. [type] Present if the flags byte has the least significant bit set (0×01). len4 Four byte length of content.
Pipe Binding Protocol
The Pipe Binding Protocol is used to create virtual channels between peers. The protocol uses the Endpoint Protocol that it abstracts to allow pipes to be created that use supported transport protocols, such as the JXTA HTTP Transport, the JXTA TCP/IP Transport, or the secure JXTA TLS Transport.
To use a pipe, an advertisement must be published and then used by other peers. When a peer has a pipe advertisement, the peer makes a pipe bind request, which is responded to by a peer accepting the pipe.
- To bind the pipe, there is a pipe bind request and a pipe bind response. The request for a pipe has the following data:
- MsgType—Defines this message as a query an answer. For the query, it will be Query.
PipeId—Pipe ID being resolved.
- Type—The type of pipe resolution requested.
- Cached—False if the answer can not come from the cache.
- Peer—A peer ID of the only peer that is to answer that request. This tag is not required because, in many instances, you do not explicitly connect to a specific peer.
The reply to a pipe bind uses the same schema, but there are additional tags and a slightly different interpretation applied to their contents. With the data from both messages, the Pipe Binding Protocol can use the Endpoint Protocol to create a route between peers and select the appropriate protocol based on the peers involved. The following is the reply message that contains the other peer that can then be used to locate the other peer’s endpoint:
- MsgType—Defines this message as a query an answer. For the answer, it will be Answer.
- PipeId—The Pipe ID being resolved.
- Type—The type of pipe resolution requested.
- Found—Response value showing success or failure that an Input Pipe was found on the specified peer.
- PeerAdv—Peer Advertisement of the peer that connects to the Input Pipe.
The following is the XML schema for the pipe-binding message:<xs:element name="PipeResolver" type="jxta:PipeResolver"/> <xs:complexType name="PipeResolver"> <!-- should be an enumeration choice --> <xs:element name="MsgType" type="xs:string"/> <xs:element name="PipeId" type="xs:anyURI"/> <xs:element name="Type" type="xs:string"/> <!-- used in the query --> <xs:element name="Cached" type="xs:boolean" default="true" minOccurs="0"/> <xs:element name="Peer" type="xs:anyURI" minOccurs="0"/> <!-- used in the answer --> <xs:element name="Found" type="xs:boolean" minOccurs="0"/> <!--This should refer to a peer adv, but is instead a whole doc--> <xs:element name="PeerAdv" type="xs:string" minOccurs="0"/> </xs:complexType>
The resolver is used to send queries throughout the P2P network. The resolver is used by base services, such as the discovery mechanism to search for advertisements. You can also use the resolver when you have a query response model of communication where answers come from a group of peers rather than a specific peer.
The following is the XML schema for the ResolverQuery message:<xs:element name="ResolverQuery" type="jxta:ResolverQuery"/> <xs:complexType name="ResolverQuery"> <xs:element name="Credential" type="xs:anyType" minOccurs="0"/> <xs:element name="SrcPeerID" type="xs:anyURI"/> <!-- This could be extended with a pattern restriction --> <xs:element name="HandlerName" type="xs:string"/> <xs:element name="QueryID" type="xs:string"/> <xs:element name="Query" type="xs:anyType"/> </xs:complexType>
The following is an explanation of the tags:
- Credential—This is the credential of the peer sending the query.
- HandlerName—The name associated with a resolver handler that listens for messages of this type.
- QueryID An ID that is used to link to the response. This ID is important because the order of responses to queries is not guaranteed. It is also used in case there are duplicate responses to the query, which is also possible.
- Query—This is where you put application data for the other peers to examine. If you plan on an XML message, the message must be escaped.
The following is the XML schema for a ResolverResponse message:<xs:element name="ResolverResponse" type="ResolverResponse"/> <xs:complexType name="ResolverResponse"> <xs:element name="Credential" type="xs:anyType" minOccurs="0"/> <xs:element name="HandlerName" type="xs:string"/> <xs:element name="QueryID" type="xs:string"/> <xs:element name="Response" type="xs:anyType"/> </xs:complexType>
What follows is an explanation of the tags for the resolver response message:
- Credential—This is the credential of the peer sending the response.
- HandlerName—The name associated with a resolver handler that listens for messages of this type.
- QueryID—An ID that is used to link to the query. This ID is important because the order of responses to queries is not guaranteed. It is also used in case there are duplicate responses to the query, which is also possible.
- Response—This is where you put application data for the other peers to examine. If you plan on an XML message, the message must be escaped.
The Rendezvous Protocol describes how messages are propagated peers in the member group. The Rendezvous Protocol uses the Peer Endpoint Protocol to locate the peers in the group and determine routes and transports. The Peer Resolver Protocol uses the Rendezvous Protocol to send messages, so you should not access the Rendezvous Protocol or its implementation directly.
Even though the Resolver Protocol should be used instead of the rendezvous, it is important to understand the messaging that occurs to get an idea of how messages flow in the system.
Rendezvous Advertisement (RdvAdvertisement)
The Rendezvous Advertisement (RdvAdvertisement) is very simple and only has the following three tags:
- Name—Name of the rendezvous peer
- RdvGroupId—PeerGroup UUID
- RdvPeerId—Peer ID of the rendezvous peer
The connection between a peer and a rendezvous peer is achieved by a connection, associated with a lease. A lease is a concept that basically means that the connection is promised for a certain period of time. The lease must be requested before the connection is allowed. When the lease is granted by the rendezvous, the peer can begin using the connection until the lease expires or the lease is canceled by the peer or the rendezvous. The length of the lease is determined by the rendezvous and is not guaranteed to expire normally. When a peer is done with the connection, it can send a cancel request, which, if granted, the rendezvous will reply with a lease canceled message.A set of queries and responses are defined by the Rendezvous Protocol to establish connections:
- LeaseRequest—Message a peer uses to request a connection to a rendezvous. A rendezvous that grants a connection lease returns the LeaseGranted message.
- LeaseGranted—Message sent by a rendezvous to indicate the lease has been granted.
- LeaseCancelRequest—Message is sent by a client to its rendezvous to cancel an existing lease. The rendezvous should reply with LeaseCancelled, but this is not guaranteed.
Determining three qualities about each message received controls propagation. First is its time to live (TTL) parameter. If the message has expired, the message is ignored. Second is the loop; if the message has been seen before, it is discarded. Third is the duplicate that tests to see if the message has been processed.
The reason for loop and duplicate tests is that a looped message is a message that has already been ignored or processed while the duplicate test checks to see if it was processed. A message may be handled differently if it is looped but not yet processed. This is because the rendezvous may discard a message, process it, or be interested but not at this instant. A message must be alive, not processed and not looped, before it can be processed completely. It may be optionally processed if it is still alive, has looped, but not processed.
Remember that a propagated message may be seen several times by the rendezvous. By using the path, the TTL, and the ID of the message, the rendezvous can avoid forwarding messages to peers that have already seen the message or that the rendezvous has already processed itself.
This control is accomplished by adding a RendezVousPropagateMessage message element within each propagated message. The XML schema for the element is as follows:<xs:element name="RendezVousPropagateMessage" type="jxta:RendezVousPropagateMessage"/> <xs:complexType name="RendezVousPropagateMessage"> <xs:element name="MessageId" type="xs:string"/> <!-- This should be a constrained subtype --> <xs:element name="DestSName" type="xs:string"/> <xs:element name="DestSParam" type="xs:string"/> <xs:element name="TTL" type="xs:unsignedInt"/> <xs:element name="Path" type="xs:anyURI" maxOccurs="unbounded"/> </xs:complexType>
The RendezVousPropagateMessage holds the information used by the rendezvous to determine specific information about the message and its routing.
JXTA has many identifiers. We have shown most of them earlier in the chapter as parts of the advertisements. They are used for identification, indexing, and searching. There are usually two specific identifiers in most advertisements. The first is the advertisement ID. This ID is generated when the advertisement is created. One way to look at the advertisement identifier is that it is like an object reference. The identifier has no real value other than to give each advertisement a unique number. The second identifier is one associated with the advertisement type.
The format of identifiers vary according to their intent and use. Identifiers vary from simple names to unique identifiers that can consist of rather long sequences of numbers and letters (please refer to the earlier section titled “Modules” for examples of the different identifiers).
Codat is an invented word that is short for “code and data.” In the documentation of the Codat class, we find the following definition:
The JXTA platform defines Codat as the unit of information shared and exchanged within a JXTA group. All instances of Codats reside within a peer group. The PeerGroup content caching service provides storage and retrieval methods for codats using codatId as index.
A codat, therefore, represents data and can contain code or a reference to code. In a group advertisement, the code is defined by the service definitions in the parms tag. These service advertisements have unique names that reference code implementations.
A Codat ID is defined in the JXTA spec as follows:
Codat IDs refer to codats. A Codat ID should canonically, uniquely and unambiguously refer to a codat. ID Formats may OPTIONALLY support this ID Type. If a JXTA binding recognizes the ID Format, it should be able to extract a Peer Group ID from a Codat ID. This Peer Group ID identifies the peer group to which the codat belongs.
In the definition, canonical simply means unique. To say it more precisely, there is no more than one ID or official name for the same resource. On the Web, an HTTP URL is a canonical name for a Web page.
The peer ID is a reference to a specific peer. The peer ID is valid for the time that the peer exists. Because peers are persistent, the peer ID is reused each time the JXTA peer is started. The only time the peer ID is destroyed is when you delete the configuration manually or uninstall the peer platform. The next time the peer is started, a new peer ID will be created.
Peer group IDs are used to locate and index groups. The lifetime of a group ID is variable. Public groups do not change. Groups that are temporary should have an expiration associated with them. It is up to the group creator to define the lifetime of the group.
The service ID is used to define a codat. The ID is associated with a unique piece of code.
The pipe ID is used to advertise a communications channel within a group or service. The pipe is often only valid for the running time of an application. In at least the initial versions of JXTA, the pipe ID has a very good chance of being invalid. It is possible to reuse a pipe ID, but this is not of much use. The pipe ID also contains the ID of its parent group to help with indexing and verification of the group context.
This chapter has covered the top layer of the JXTA protocols. You should at least have a grasp of how JXTA works and its key systems. You should now also understand P2P networking and P2P applications a little better.
We have not gone too deeply into the protocol because this should be all you need to begin understanding how JXTA works. Remember, the JXTA protocol is really just a set of messages. So far, we are just brushing the surface of JXTA. The protocol is relatively useless without a platform that implements it. You also need to know how we can take advantage of the protocol.
About the Author
Daniel Brookshier is a world-class Java consultant, author, and speaker with 20 years of experience. Mr. Brookshier’s knowledge of software development covers many industries, including transportation, telecom, wireless, healthcare, B2B, petroleum engineering, law, insurance, software tools, and aerospace. He is an international consultant with contract assignments in the United States, Norway, the United Kingdom, and China. Mr. Brookshier is the founder of two Java user groups in Dallas, Texas, the writer of several Java programming books, and he has published numerous articles about Java in industry magazines. Daniel is a recognized expert on Java software development, Java standards, Java Management, enterprise software, and JavaBeans component development. Daniel can be reached at firstname.lastname@example.org
JXTA: Java P2P Programming 0-672-32366-4 by Daniel Brookshier, Darren Govoni, Navaneeth Krishnan, and Juan Carlos Soto
Source of this material
This material is from Chapter 2, Overview of JXTA, from the book JXTA: Java P2P Programming (ISBN: 0-672-32366-4) written by Daniel Brookshier, Darren Govoni, Navaneeth Krishnan, and Juan Carlos Soto, published by Sams Publishing. .© Copyright Pearson Education. All rights reserved.