See: Description
Interface | Description |
---|---|
Waterfall |
The Waterfall interface must be implemented by call-back classes that will
be called by a Lake object when a new River is received from a remote host.
|
Class | Description |
---|---|
Iceberg |
The Iceberg class is the encapsulation of a portion of data, similar to a
frame (or packet) of data (which is normally stored in compressed form).
|
Iceberg.Constants |
Iceberg.Constants class provides sets of various constants used in the
implementation of the protocol.
|
Lake |
The Lake class handles the details of communications in a standard way for
both the client and the server.
|
River |
The River class is connected to the Lake and provides a collection of
methods for accessing both the RiverInputStream and RiverOutputStream, and
various protocol-specific functions designed for specific communication over
through the Streams.
|
RiverInputStream |
The RiverInputStream class provides InputStream-like methods for receiving
data.
|
RiverOutputStream |
The RiverOutputStream class provides OutputStream-like methods for sending
data.
|
Exception | Description |
---|---|
IcebergException |
An IcebergException occurs if a problem is encountered with the data (e.g.,
the compressed data is corrupt, the length header field doesn't match the
actual size of the data, etc.).
|
These are Client/Server internet I/O classes that encapsulate multiple sets of streams over a single Socket connection (the use of TLS/SSL Sockets is strongly encouraged, but not required). A few key advantages with these classes is that server Operating Systems ultimately don't need to be configured to support as many socket connections, initialization/authentication steps don't need to be repeated (as may normally be the case when opening additional sockets), and built-in compression can help to reduce bandwidth requirements.
A metaphorical theme involving bodies of water and water pathways helps to avoid potential class-naming conflicts with the standard Java I/O stream libraries and some currently-known third-party Java I/O libraries. The starting point is the instantiation of a Lake with a few key parameters - particularly a Socket - from which Rivers flow via I/O Streams, creating a Waterfall for each new River as it is received. The following ASCII art diagram provides a generalized depiction of the relation between these classes:
A = Iceberg (data) ,--._ .---. ,~~~ RiverInputStream : = Waterfall __ ( `"--' A }=== River ==={ ,-" `". ) A ( ID +1 `~~~ RiverOutputStream }===[Socket]~~~{ A A \__.' A ) | : :| ) A A A ( |: : | ( A A ". ,~~~ RiverInputStream | : : | `----._ A Lake A }=== River ==={ |'. '.'| ) ,-. A ,' ID -1 `~~~ RiverOutputStream |o.oO.o| _,' ( `--" ,-"^^^^^^^^"-----'" A ___ ) ( ' . ' A . ' _,-'" `", A `"'-. ,~~~ RiverInputStream `._ ` ' , . `_,-' `-_ A A }=== River ==={ `"----------"' `"---' ID +2 `~~~ RiverOutputStream |
The Socket is the encapsulating conduit between Lakes. The Lake is host to any number of Rivers, each of which encapsulates a RiverInputStream and a RiverOutputStream (these are the I/O streams). When a new River is created, the other Lake at the remote endpoint of the Socket instantiates a Waterfall and initiates the necessary callback.
An Iceberg is an immutable portion of data, which is transmitted over the Socket, usually in compressed form (compression is handled automatically by the Iceberg class as an internal function, and uses the Java standard library's built-in GZip algorithm that is typically not CPU-intensive compared to other algorithms that yield better compression ratios albeit with a performance penalty -- most of the emphasis is on speed over size). An Iceberg can also carry "functional" information (e.g., to notify end-of-stream) which won't be included in the stream of data (see the Iceberg class documentation for more information).
Every new River is automatically assigned a unique 16-bit ID number internally by its respective Lake. To prevent ID number collisions between Lakes, positive ID numbers are assigned to the client-side Lake and negative ID numbers are assigned to the server-side Lake. When an Iceberg is received by a Lake via a new River, a Waterfall callback is initiated.