 |
Demystifying Pipes, JxtaSockets, JxtaMulticastSocket, and JxtaBiDiPipes
Posted by hamada on August 23, 2005 at 09:20 AM | Comments (12)
Lately there has been several inquiries about JXTA's PipeService, and companion utilities (JxtaSocket, JxtaMulticastSocket, and JxtaBiDiPipe) on JXTA's discussion lists, hence this blog to shed more light on the PipeService and utilities provided, and their inherit features.
The initial goal of the PipeService was to provide primitive (unidirectional, and unreliable) message based communication channels upon which complex and sophisticated communication channels can be built. The PipeService provides three types of pipes described as follows:
JxtaUnicast
- Unidirectional
- Unreliable
- Many to one
- Limited to 64KB messages
JxtaUnicastSecure
- Unidirectional
- Limited reliability (no direct notification of failures other than channel failure)
- Many to one
- Limited to 64KB messages
JxtaPropagate
- Multidirectional (many to many)
- Unreliable
- Limited to 64KB messages in infrastructure mode, and limited by physical transport limitation where applicable

JXTA JSE platform software stack
Unicast pipes (clear, and secure) are bound by the PipeResolver, which provides two modes of bindings, a static (where a set of peers is specified), and a dynamic (no peers specified) binding. Static binding is beneficial in constraining communication to a limited set of peers, while dynamic is beneficial in implementing unconstrained mobile communication channels. Both modes can be utilized in implementing fault tolerant communication channels.
Propagated pipes employ a mechanism similar to that of IGMP, where a creation of an input pipe results in propagated pipe channel join message (a pipe SRDI message to a the peer's rendezvous). In infrastructure mode propagated pipe messages are sent to the rendezvous for propagation to the subscribers of the propagated pipe channel, while in ad-hoc mode messages are propagated over the endpoint (currently only the TCP transport supports such function over multicast). A pipe closure results in a channel resign message (a pipe SRDI message to the rendezvous expiring the previous join). It's worth noting that the PipeResolver plays no part in binding of such pipe type
Pipe Binding
An InputPipe creation results in the creation of an endpoint incoming messenger, and an SRDI message with the pipe ID with an infinite expiration time. Once the InputPipe is closed another SRDI message is emitted with the pipe ID, and expiration time of 0, invalidating any reference for the pipe and peer. Note: This behavior applies to all pipe types.
An output pipe creation results in a PipeResolver query message emitted querying for instances of the pipe. A match results in a PipeResolver response to the querying peer, where an endpoint messenger to responding peer is created. Note that such messenger may not be fully resolved until the EndpointRouter has determined a valid route. During such event few messages maybe queued (3 to be exact) until the messenger has been resolved. In addition, as part of the pipe resolver protocol the pipe resolver periodically reattempts pipe resolutions in the background to validate resolved pipe endpoints. It is through this mechanisms pipes can migrate from one peer to another. note: this behavior is limited to unicast pipe types.

SRDI message path within the JXTA network
Pipe Endpoint
A pipe endpoint is composed of a peer, group, and pipe ID, through this definition there are two inherit modes of pipe endpoint migration:
- Peer endpoint migration, an inherit feature of the Endpoint-Router, where a peer may change physical, or virtual addresses.
- Pipe endpoint migration, where a pipe endpoint ceases to exists on a peer, where the PipeResolver, attempts to rebind to the pipe (which I always refer to as a virtual channel)
The first mode is transparent the application, while the second may result in an IOException.
Reliability
A standalone message and stream based reliability layer over non reliable messengers, is provided in the platform to facilitate reliable communication channels.
Reliability Library
- Ensures message sequencing
- Interfaces to pipes or messengers
- Ensures delivery
- Exposes message, and stream interfaces
- Spawns a single thread to deal with retransmission
- Does not ensure message integrity
Bidirectional communication channels
JxtaServerSocket, and JxtaServerPipe expose a input pipe to process connection requests and negotiate communication parameters, whereby a JxtaSocket, or JxtaBiDipipe bind to respectively to establish private dedicated pipes independent of the connection request pipe. JxtaSocket, and JxtaBiDiPipe utilize a messenger instead of an output pipe for the back channel to reduce connection latency (avoids 4 messages), therefore only peer endpoint migration is inherited, and one should always expect an IOException if a PipeEndpoint migrates, or ceases to exist.
JxtaSocket, JxtaServerSocket
- Subclass java.net.Socket, and java.net.ServerSocket respectively
- Built on top of pipes, endpoint messengers, and the reliability library
- Provides bidirectional and reliable communication channels
- Exposes stream based interface a la Socket
- Provides configurable internal buffering, and message chunking
- Does not implement the Nagels algorithm, therefore streams must be flushed as needed (a common oversight when wrapping object and data streams over the socket stream)
JxtaBiDiPipe, JxtaServerPipe
- Built on top of pipes, endpoint messengers, and the reliability library
- Provides bidirectional and reliable communication channels
- Exposes message based interface
- Requires no heart beat to maintain an open connection
- Provides no message chunking
Multidirectional communication utility
JxtaMulticastSocket extends java.net.MutlicastSocket and provides mutlicast functionality over JXTA propagated pipes.
JxtaMulticastSocket
- Subclass java.net.MulticastSocket
- Built on top of propagated pipes
- Exposes datagram based interface a la MulticastSocket
- Provides unicasting through datagram addressing
Message size and limiting factors
- The JXTA platform imposes a soft MTU of 64KB (which becomes a hard limit under load), messages exceeding MTU are simply dropped. While nodes maybe able to transmit and receive messages larger than 64KB, it is strongly advised this limit is not exceeded in reliable mode, as it will result in failed or broken channels.
- When utilizing relay peers, such limit must not be exceeded in either mode (reliable or otherwise) as the relay nodes are likely to be loaded and/or the fairness message queue size quotas are enforced, thus leading to message loss and consequently failed or broken channels.
Common pitfalls
- Pipe advertisement mismatch. Typically occurs when dynamically creating and discovering pipe advertisements using non unique identifiers, or deterministic method. Normally overcome through hardcoded pipe advertisements (or pipe ID's), encoded pipe ID's.
- Un-synchronized pipe binding. Typically caused by network islands, which are joined at a later point in time. Easily overcome through rendezvous event listener prior to any binding attempt.
- Failed Secure pipe connections. Typically due to failure of establishing NetPeerGroup credentials (TLS resides in the NetPeerGroup, and inherited by all sub-groups), or missing a trusted certificate or certificate chain in PSE. This is overcome by establishing NetPeerGroup credentials, and ensuring the perspective trusted certificate or certificate chain is stored into PSE (See the shell command pse.importcert).
Bookmark blog post: del.icio.us Digg DZone Furl Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment
-
M,
Thanks very much for this introduction. It's still a lot to absorb and a bit confusing. Can you provide some examples as to when you would use which kind of message passing? I suppose the general consensus is JXTA application programmers should avoid the use of the low-level Pipes and Propagate classes and focus on the various Jxta*Socket and the Bidi/ServerPipes. Between these two, then, when would you use the socket classes and when might you need to use the pipes? What did you mean by '# Requires no heart beat to maintain an open connection'?
Posted by: ocean on August 23, 2005 at 10:18 AM
-
Low level pipes are still useful and have their uses, as they are lightweight, and asynchronous. The intent is to shed more light on the companion utilities and their features, as well as inherit features. The general recommendation to utilize the JxtaSocket, and JxtaBiDiPipe where bidirectional and reliability is needed, keeping in mind the interface difference, the asynchronous interface JxtaBiDiPipe provides. As for the JxtaMutlicastSocket it offers portability (datagram interface), and convenience (unicasting).
Q: What did you mean by '# Requires no heart beat to maintain an open connection'?
A: JxtaBiDiPipe ensures the reliability layer does not close the underlying channel due to inactivity, thus providing a lightweight bidirectional channel.
Posted by: hamada on August 23, 2005 at 10:56 AM
-
I'm not a big fan of JMS, but I'm looking for something that is reliable and has failover built in-- grid computing. For business applications, the communication has to be reliable and persistent. I JXTA worth looking at without requiring me to write a ton of code to provide reliablility and failover?
Posted by: jhook on August 24, 2005 at 08:01 AM
-
JXTA is definitely worth a look. Although it does not offer persistent message store, it is not difficult to add such support. It should be fairly straight forward to port an application on top JXTA with code and effort. The tutorials should be a good start http://www.jxta.org/docs/JxtaProgGuide_v2.3.pdf,
http://www.jxta.org/ProgGuideExamples.zip
Let me know how things go. Cheers
M.
Posted by: hamada on August 24, 2005 at 04:14 PM
-
Thanks for the detailed info, Mohamed. I have a couple of slightly off-topic questions with regard to this article, though:
In the platform software stack diagram, what does RF refer to?
Would it be acceptable to reproduce this diagram? If so, is there a particular attribution you would prefer?
Posted by: vwilliams on August 25, 2005 at 02:27 PM
-
I listed RF (Radio Frequency) to highlight that JXTA is not limited to IP. You can certainly reproduce them, and I have no attribution preference.
Posted by: hamada on August 25, 2005 at 02:43 PM
-
Thanks. Your explanation about communication in Jxta was really nice, Mohamed. By the way, I have been following the heroic efforts that you and Vanessa Williams (among others, I think) are doing to fix JxtaSockets' insidious bugs.
Have the JxtaSocket bugs been already ripped off? I am currently working with JxtaBiDiPipe, but I would like to come back to JxtaSocket as soon as possible.
Posted by: edward_ribeiro on August 27, 2005 at 08:55 AM
-
Thanks for the feedback. JxtaSosckets (under load), suffered from reliabily closing connections. This problem has since been addressed, so feel free to switch back.
Cheers
Posted by: hamada on August 27, 2005 at 10:37 AM
-
Thanks for the explaination about pipes and BiDi pipes.
Is there an upper bound on the number of messages that pipes can handle at any instant of time?
I have increased the endpoint queue size to 9999 in the configuration file ("endpoint queueSize="9999" ") and I still seem to get
" Could not enqueue net.jxta.endpoint.Message@12141980(6){121364} for sending. "
error .
Posted by: anne06 on November 24, 2005 at 12:06 PM
-
The endpoint imposes message quotas to ensure no one application/service/peer saturates the the endpoint. These parameters are hard-coded at the moment in QuotaIncomingMessageListener, and probably be made tunable dynamically.
Posted by: hamada on November 25, 2005 at 04:44 PM
-
Thank you for the reply, BiDi pipes are reliable for my application. I am surprised that BIDI which also uses the endpoint does not seem to have any restrictions for the message quota. I am unable to find any write up about the reliabilty library and how reliabilty is ensured in JXTA. Could you kindly point me to a resource.
Thanks
Posted by: anne06 on November 28, 2005 at 06:27 PM
-
Hi,Mohamed.I have a problem about JxtaUnicastSecure.I can run my project with JxtaUnicast pipeAdvertiemsnt,But I learn about that JxtaUnicatSecure pipeAdvertisment is safe when we translate data.However I couldn't run my project when I use JxtaUnicastSecure pipeAdvertisement.The wrong information is :
Could not enqueue net.jxta.endpoint.Message@31637242(3){152} for sending. Pipe is closed.
Can you give me some suggestion?Thank you.
Posted by: maxingkong on March 31, 2007 at 01:14 AM
|