PIRL

PIRL.Messenger
Class Messenger

java.lang.Object
  extended by PIRL.Messenger.Messenger

public class Messenger
extends Object

A Messenger sends and receives Messages over a communication channel and routes received messages to their destination.

Client Communication

A Messenger has a client communication channel to which Messages may be sent and from which they may be received. Messages may be received synchronously or asynchronously. A message that is received synchronously is returned directly to the caller. A timeout for synchronous message receipt may be specified to prevent indefinate blocking if no message arrives. Because only one communication channel is used for receiving messages synchronous receiving of messages can not be done while messages are being received asynchronously. Messages are received asynchronously on a separate message reader thread which waits indefinately until a message arrives and then dispatches the message based on its address routing information.

Sending and receiving of messages is thread safe. A Message will be completely sent before another will be allowed to be sent. A Message will be completely received and delivered before another will be received. A Message may be sent by one thread while a Message is being received and delivered by another thread. While a Message is being sent or received and delivered another thread trying to do the same operation will be blocked until the current operation completes. Message level synchronization ensures that Messages will not collide and be corrupted during transmission.

The client communication channel may be closed at any time at either end of the channel. When the channel is closed an explanation may be provided which is then delivered in a Message to the Messenger Employer. This offers the employer an opportunity to take appropriate action. Once the client communication channel is closed in can not be reopened. To reopen communication with the client a new Messenger must be constructed.

Message Routing

Messages received asynchronously are examined for routing information. Each Messenger has a unique address which is always added to a Message's route-from list when it is sent. On receipt if the last entry of a Message's route-to list is the address of the receiving Messenger, or the route-to list is empty, the Message is delivered to the Messenger employer. If the address matches that of a forwarding Messenger it is used to send the Message. If the address is unknown the Message is sent back with an appropriate undeliverable notation.

Message Content

In addition to routing information contained in the Message label, the Message body may have any content that can be represented using Parameter Value Language (PVL) formatting.

The input stream that is read is assumed to have one character per byte. This is because a Message is based on PVL formatted syntax using US-ASCII encoded text. The message start synchronization sequence, which is critical for identifying the location of a message in the communication channel byte stream, must be composed of the required ASCII characters if it is to be recognized (this is done automatically by the Message class). Multi-byte message body characters and binary data may be transmitted in ASCII transcoded form such as standard HTML character references for multi-byte characters and hexadecimal value character pairs for binary bytes, but it is the responsibility of the application using the delivered Message to interpret transcoded sequences.

Message Statistics

A count of the total number of Messages successfully sent and received is maintained. Also a count of Messages dropped because they could not be sent or received for any reason is maintained. If a Message can not be sent or received due to a problem with the client communication channel the channel is closed and the Messenger employer is notified with a Done Message.

Version:
1.65
Author:
Bradford Castalia, UA/PIRL
See Also:
Message

Field Summary
static String ACTION_PARAMETER_NAME
          Message parameter specifying the action associated with a Message.
static String ADDRESS_PARAMETER_NAME
          Identity Message parameter set to contain the Messenger Address.
static char ADDRESS_SEGMENT_DELIMITER
          The delimiter character separating the sections of a Messenger address.
static SimpleDateFormat DATE_FORMAT
          Date formatter used to represent the Messenger start time.
static String DATE_FORMATTING
          The DATE_FORMAT pattern.
static int DEFAULT_BUFFER_INCREMENT
          The read buffer size increment.
static int DEFAULT_CLOSE_TIME
          The amount of time, in seconds, to wait for closing a socket to complete.
static int DEFAULT_CONNECT_TIMEOUT
          The amount of time, in seconds, to wait for a server connection.
static String EXCEPTION_PARAMETER_NAME
          A parameter containing an exception description.
static String EXPLANATION_PARAMETER_NAME
          A parameter containing an explanation description.
static String FORWARDING_MESSENGERS_PARAMETER_NAME
          The name of the forwarding Messengers identities parameter group.
static String ID
          Class identification name with source code version and date.
protected  Message Identity
          An optional Message containing parameters used to identify the Messenger by employer applications.
static String IDENTITY_PARAMETER_NAME
          The name given to an Identity Message.
static int MAX_LABEL_LENGTH_DIGITS
          Maximum number of digits in the message label length value sequence.
static int MAX_RECONNECT_ATTEMPTS
          The maximum number of repeated server reconnect tries.
static String MESSENGER_ADDRESS_PARAMETER_NAME
          Message ACTION_PARAMETER_NAME value sent in response to receiving an ADDRESS_PARAMETER_NAME action Message for delivery.
static int MINIMUM_BUFFER_SIZE
          The minimum size of the read buffer.
static String NAME_PARAMETER_NAME
          The name of the identity parameter that provides the name of the Messenger being identified.
static String ORIGINAL_MESSAGE_PARAMETER_NAME
          Group of parameters containing the bounced message in an UNDELIVERABLE_ACTION Message.
static String ROUTE_FROM_PARAMETER_NAME
          Message label parameter whose value is the message route-from list.
static String ROUTE_TO_PARAMETER_NAME
          Message label parameter whose value is the message route-to list.
static String UNDELIVERABLE_ACTION
          Bounced message due to unknown route-to address Message ACTION_PARAMETER_NAME value.
 
Constructor Summary
Messenger(Message_Delivered_Listener employer, InetSocketAddress client_address)
          Construct a Messenger on a client's connection address.
Messenger(Message_Delivered_Listener employer, SocketChannel client_channel)
          Construct a Messenger on a client's communication channel connection.
Messenger(Message_Delivered_Listener employer, String host, int port)
          Construct a Messenger to a client on a specified host and port.
Messenger(String host, int port)
          Construct a Messenger to a client on a specified host and port.
 
Method Summary
 Messenger Add_Forwarding(Messenger messenger)
          Add a Messenger to the Message forwarding list.
 String Address()
          Get the address of this Messenger.
 int Buffer_Capacity()
          Get the capacity of the read buffer.
 int Buffer_Increment()
          Get the read buffer increment amount.
 Messenger Buffer_Increment(int amount)
          Set the read buffer increment amount.
 SocketChannel Client_Channel()
          Get the client communication channel.
 String Client_Hostname()
          Get the connonical, fully qualified hostname for the remote host to which the Messenger communication channel is connected.
 int Client_Port()
          Get the remote port number of the Message communication channel.
static void Configure_Socket(Socket socket)
          Configures a Socket.
static int Connect_Timeout()
          Get the amount of time, in seconds, to wait for the communication channel to connect.
static void Connect_Timeout(int timeout)
          Set the amount of time, in seconds, to wait for the communication channel to connect.
static SocketChannel Connect(SocketAddress address)
          Connect to a SocketAddress.
static int Default_Buffer_Increment()
          Get the current default read buffer increment amount.
static int Default_Buffer_Increment(int amount)
          Set the default size to use for the read buffer increment.
protected  void Deliver(Message message)
          Deliver a Message locally.
 boolean Done()
          Force the Messenger to close its client communication channel.
 void Done(String explanation)
          Force the Messenger to close its communication channel and deliver a Done Message.
 void Done(String explanation, Exception exception)
          Deliver a Done Message to the employer and close its communication channel.
 Message_Delivered_Listener Employer()
          Get the Messenger employer.
 Messenger Employer(Message_Delivered_Listener employer)
          Set the Messenger employer.
 Exception Error_Condition()
          Get the most recent error exception.
 Messenger Forwarding_Messenger(String address)
          Get the Messenger associated with a forwarding address.
 Message Forwarding_Messengers()
          Get the identities of all Messengers in the forwarding list.
 Message Identity()
          Get the Message describing the identity of this Messenger.
 Messenger Identity(Message identity)
          Set the identity of this Messenger.
 boolean Is_Connected()
          Test if the Messenger's communication channel is connected to the client.
 Thread Listen_for_Messages()
          Start the Messenger thread listening for messages.
 boolean Listening_for_Messages()
          Test if the Messenger thread is running and marked to continue listening for messages.
 long Message_Bytes_Received()
          Get the number of message bytes received.
 long Message_Bytes_Sent()
          Get the number of message bytes sent.
static ThreadGroup Message_Listeners()
          Get the group of all message listener threads.
 long Messages_Received_Corrupted()
          Get the number of Messages received that were corrupted in transmission.
 long Messages_Received_Dropped()
          Get the number of Messages that were dropped becasue they could not be completely received.
 long Messages_Received()
          Get the number of Messages successfully received.
 long Messages_Sent_Corrupted()
          Get the number of Messages to be sent that had content for which a PVL representation could not be generated.
 long Messages_Sent_Dropped()
          Get the number of Messages that could not be sent.
 long Messages_Sent()
          Get the number of Messages successfully sent.
 long Messages_Unforwardable()
          Get the number of Messages that could not be forwarded.
 int Port()
          Get the local port number used to communicate Messages.
protected  Message Read_Packet(int timeout)
          Read a Message packet from the communication channel.
 Message Receive()
          Receive a message synchronously.
 Message Receive(int timeout)
          Receive a message synchronously.
 boolean Remove_Forwarding(Messenger messenger)
          Remove a Messenger from the Message forwarding list.
 Messenger Reset_Error_Condition()
          Clear the most recent error condition.
protected  void Route_Packet(Message message, ByteBuffer content)
          Route a message packet to a recipient.
protected  void Send_Packet(Message message_label, ByteBuffer content)
          Send the message packet.
 void Send(Message message)
          Send a Message over the communication channel.
 Messenger Shrink_Buffer()
          Shrink the read buffer size.
 long Start_Time()
          Get the time when this Messenger was constructed.
 boolean Stop_Listening_for_Messages()
          Flag the Messenger thread to stop listening for messages.
 String toString()
          Get a description of this Messenger.
protected  void Update_Send_Routing(Message message)
          Update the message send routing information of a Message.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

ID

public static final String ID
Class identification name with source code version and date.

See Also:
Constant Field Values

DATE_FORMATTING

public static final String DATE_FORMATTING
The DATE_FORMAT pattern.

The date format is:

d MMMMM yyyy kk:mm:ss.SSS Z

where d is the day number in the month (one or two digits), MMMMM is the full month name in the year, yyyy is the full year number, kk is the hour in the 24 hour day (two digits), mm is the minute in the hour (two digits), ss is the second in the minute (two digits), SSS is the millisecond in the second (three digits), and Z is the hours-minutes offset of the local time zone from the reference UTC zone.

See Also:
Constant Field Values

DATE_FORMAT

public static final SimpleDateFormat DATE_FORMAT
Date formatter used to represent the Messenger start time.

See Also:
DATE_FORMATTING

ADDRESS_SEGMENT_DELIMITER

public static final char ADDRESS_SEGMENT_DELIMITER
The delimiter character separating the sections of a Messenger address.

See Also:
Constant Field Values

Identity

protected Message Identity
An optional Message containing parameters used to identify the Messenger by employer applications.

The content of the message is determined by the application.


IDENTITY_PARAMETER_NAME

public static final String IDENTITY_PARAMETER_NAME
The name given to an Identity Message.

See Also:
Constant Field Values

NAME_PARAMETER_NAME

public static final String NAME_PARAMETER_NAME
The name of the identity parameter that provides the name of the Messenger being identified.

See Also:
Constant Field Values

ADDRESS_PARAMETER_NAME

public static final String ADDRESS_PARAMETER_NAME
Identity Message parameter set to contain the Messenger Address.

See Also:
Constant Field Values

MESSENGER_ADDRESS_PARAMETER_NAME

public static final String MESSENGER_ADDRESS_PARAMETER_NAME
Message ACTION_PARAMETER_NAME value sent in response to receiving an ADDRESS_PARAMETER_NAME action Message for delivery.

See Also:
Constant Field Values

ROUTE_TO_PARAMETER_NAME

public static final String ROUTE_TO_PARAMETER_NAME
Message label parameter whose value is the message route-to list.

See Also:
Message.Packet_Label(int), Constant Field Values

ROUTE_FROM_PARAMETER_NAME

public static final String ROUTE_FROM_PARAMETER_NAME
Message label parameter whose value is the message route-from list.

See Also:
Message.Packet_Label(int), Constant Field Values

ACTION_PARAMETER_NAME

public static final String ACTION_PARAMETER_NAME
Message parameter specifying the action associated with a Message.

See Also:
Constant Field Values

FORWARDING_MESSENGERS_PARAMETER_NAME

public static final String FORWARDING_MESSENGERS_PARAMETER_NAME
The name of the forwarding Messengers identities parameter group.

See Also:
Constant Field Values

MAX_LABEL_LENGTH_DIGITS

public static final int MAX_LABEL_LENGTH_DIGITS
Maximum number of digits in the message label length value sequence.

The message start synchronization sequence includes the length of the message label section as a decimal integer value. The text representation of the label length value has a maximum number of digits for a reasonable value. Seven digits should be more than sufficient for the largest reasonable label length values.

See Also:
DEFAULT_BUFFER_INCREMENT, Constant Field Values

MINIMUM_BUFFER_SIZE

public static final int MINIMUM_BUFFER_SIZE
The minimum size of the read buffer.

The minimum read buffer size must allow for the Message start synchronization sequence:

  1. Message.START_MARKER
  2. Message.START_MARKER_DELIMITER
  3. Up to MAX_LABEL_LENGTH_DIGITS
  4. Message.START_MARKER_END

See Also:
DEFAULT_BUFFER_INCREMENT

DEFAULT_BUFFER_INCREMENT

public static final int DEFAULT_BUFFER_INCREMENT
The read buffer size increment.

When additional read buffer capacity is needed for storing an incoming message the buffer size is increased by a multiple of the size increment to at least the required capacity. It follows that the initital read buffer size is the size increment.

A reasonable buffer size increment will not be too small so that buffer expansion reallocation and data content copying will not need to happen too often; yet not so large that an excessive buffer size will result. It must not be smaller than the MINIMUM_BUFFER_SIZE. The read buffer size will be increased as needed, but never decreased unless Shrink_Buffer() is called.

See Also:
Constant Field Values

UNDELIVERABLE_ACTION

public static final String UNDELIVERABLE_ACTION
Bounced message due to unknown route-to address Message ACTION_PARAMETER_NAME value.

See Also:
Constant Field Values

ORIGINAL_MESSAGE_PARAMETER_NAME

public static final String ORIGINAL_MESSAGE_PARAMETER_NAME
Group of parameters containing the bounced message in an UNDELIVERABLE_ACTION Message.

See Also:
Constant Field Values

EXPLANATION_PARAMETER_NAME

public static final String EXPLANATION_PARAMETER_NAME
A parameter containing an explanation description.

See Also:
Constant Field Values

EXCEPTION_PARAMETER_NAME

public static final String EXCEPTION_PARAMETER_NAME
A parameter containing an exception description.

See Also:
Constant Field Values

DEFAULT_CONNECT_TIMEOUT

public static final int DEFAULT_CONNECT_TIMEOUT
The amount of time, in seconds, to wait for a server connection.

See Also:
Constant Field Values

MAX_RECONNECT_ATTEMPTS

public static final int MAX_RECONNECT_ATTEMPTS
The maximum number of repeated server reconnect tries.

See Also:
Constant Field Values

DEFAULT_CLOSE_TIME

public static final int DEFAULT_CLOSE_TIME
The amount of time, in seconds, to wait for closing a socket to complete.

See Also:
Constant Field Values
Constructor Detail

Messenger

public Messenger(Message_Delivered_Listener employer,
                 SocketChannel client_channel)
          throws IllegalArgumentException
Construct a Messenger on a client's communication channel connection.

The address and identity are intialized.

Parameters:
employer - The Message_Delivered_Listener to which messages will be delivered that are not automatically forwared. If null, messages can only be received synchronously until an employer is assigned.
client_channel - The SocketChannel to which messages will be sent and from which they will be received.
Throws:
IllegalArgumentException - If the client is null.

Messenger

public Messenger(Message_Delivered_Listener employer,
                 InetSocketAddress client_address)
          throws IllegalArgumentException,
                 IOException
Construct a Messenger on a client's connection address.

The client address is used to connect to the client's communication channel.

The address and identity are intialized.

Parameters:
employer - The Message_Delivered_Listener to which messages will be delivered that are not automatically forwared. If null, messages can only be received synchronously until an employer is assigned.
client_address - An InetSocketAddress to be used in establishing a communication channel with the client.
Throws:
IllegalArgumentException - If either the employer or server is null.
IOException - If there was a problem connecting to the server.
See Also:
Messenger(Message_Delivered_Listener, SocketChannel)

Messenger

public Messenger(Message_Delivered_Listener employer,
                 String host,
                 int port)
          throws IllegalArgumentException,
                 IOException
Construct a Messenger to a client on a specified host and port.

The hostname and port number define the address of the client where the communication channel connection is to be made.

The address and identity are intialized.

Parameters:
employer - The Message_Delivered_Listener to which messages will be delivered that are not automatically forwared. If null, messages can only be received synchronously until an employer is assigned.
host - The name or IP address of the host system where the server is running.
port - The port number on the server host system to use when establishing a connection.
Throws:
IllegalArgumentException - If either the employer or hostname is null or the port number is invalid.
IOException - If there was a problem connecting to the server.
See Also:
Messenger(Message_Delivered_Listener, InetSocketAddress)

Messenger

public Messenger(String host,
                 int port)
          throws IllegalArgumentException,
                 IOException
Construct a Messenger to a client on a specified host and port.

The hostname and port number define the address of the client where the communication channel connection is to be made.

The address and identity are intialized.

N.B.: Messages can only be received synchronously until an employer is assigned.

Parameters:
host - The name or IP address of the host system where the server is running.
port - The port number on the server host system to use when establishing a connection.
Throws:
IllegalArgumentException - If either the employer or hostname is null or the port number is invalid.
IOException - If there was a problem connecting to the server.
See Also:
Messenger(Message_Delivered_Listener, String, int)
Method Detail

Address

public String Address()
Get the address of this Messenger.

The format of the address is:

IP_ADDRESS:Port:Start_Time

where IP_ADDRESS is the Internet Protocol address of the host system, Port is the local port number used to communicate Messages, and Start_Time is the time when this Messgener was constructed. This address is used to uniquely identify this Messenger when Messages are sent and received.

Returns:
The address String for this Messenger.
See Also:
Message.Route_To(), Message.Route_From()

Start_Time

public long Start_Time()
Get the time when this Messenger was constructed.

The time is obtained from the host system as the difference, measured in milliseconds, between the Messenger construction time and midnight, January 1, 1970 UTC.


Identity

public Message Identity()
Get the Message describing the identity of this Messenger.

N.B.: A reference to, not a copy of, the identity Message is returned. This is done because the identity Message is not owned by the Messenger; it is controlled by the application.

Returns:
A Message containing parameters the identify this Messenger. This will be null if no {#Identity(Message) identity} has been assigned.

Identity

public Messenger Identity(Message identity)
Set the identity of this Messenger.

The specified Message is copied, unless it is null in which case an empty message is provided.

The identity Message may contain any parameters used by the employing application to identify this Messenger. The identity Message will be given the Name IDENTITY_PARAMETER_NAME and it will be guaranteed to contain an ADDRESS_PARAMETER_NAME with the address of this Messenger as its value. If the identity Message contains an ACTION_PARAMETER_NAME parameter it is removed.

Parameters:
identity - A Message containing parameters that describe the identity of this Messenger.
Returns:
This Messenger.

toString

public String toString()
Get a description of this Messenger.

Overrides:
toString in class Object
Returns:
A String describing this Messenger.

Connect_Timeout

public static int Connect_Timeout()
Get the amount of time, in seconds, to wait for the communication channel to connect.

Returns:
The connection timeout, in seconds.
See Also:
Connect_Timeout(int)

Connect_Timeout

public static void Connect_Timeout(int timeout)
Set the amount of time, in seconds, to wait for the communication channel to connect.

Parameters:
timeout - The connection timeout, in seconds. If less than one the DEFAULT_CONNECT_TIMEOUT will be used.
See Also:
Connect(SocketAddress)

Client_Hostname

public String Client_Hostname()
Get the connonical, fully qualified hostname for the remote host to which the Messenger communication channel is connected.

Returns:
The remote hostname String, or null if the Messenger is not connected. This may, of course, be the same as the local Host.FULL_HOSTNAME.

Client_Port

public int Client_Port()
Get the remote port number of the Message communication channel.

N.B.: The availability of a remote port number does not imply that the communication channel is connected.

Returns:
The port number on the remote host system (which, of course, may be the same as the local host system) used for Message communication. This will be 0 if the Messenger is not yet connected.

Is_Connected

public boolean Is_Connected()
Test if the Messenger's communication channel is connected to the client.

A Messenger is connected if the client communication channel is open and connected.

Returns:
true if the client communication channel is connected; false otherwise.

Client_Channel

public SocketChannel Client_Channel()
Get the client communication channel.

Returns:
The SocketChannel used for communication with the Messenger's client.
See Also:
Is_Connected()

Port

public int Port()
Get the local port number used to communicate Messages.

The port number is determined by the communication channel used to construct the Messenger. All Messages received will be read from this port and all Messages sent will be written to this port.

Returns:
The communication local port number.

Employer

public Message_Delivered_Listener Employer()
Get the Messenger employer.

Messages recieved are delivered to the employer if they are addressed to this Messanger or have no address.

Returns:
A Message_Delivered_Listener employer object.
See Also:
Message_Delivered_Listener, Employer(Message_Delivered_Listener)

Employer

public Messenger Employer(Message_Delivered_Listener employer)
Set the Messenger employer.

Messages recieved are delivered to the employer if they are addressed to this Messanger or have no address.

Parameters:
employer - A Message_Delivered_Listener employer object.
Returns:
This Messenger.
Throws:
IllegalArgumentException - If the employer is null.
See Also:
Message_Delivered_Listener

Add_Forwarding

public Messenger Add_Forwarding(Messenger messenger)
Add a Messenger to the Message forwarding list.

When a message is asynchronously received it is routed based on its route-to address list. The list of forwarding Messengers provide routing possibilities in addition to delivery to the employer of this Messenger.

Parameters:
messenger - A Messenger. If null nothing is done.
Returns:
This Messenger.
See Also:
Remove_Forwarding(Messenger), Forwarding_Messenger(String)

Remove_Forwarding

public boolean Remove_Forwarding(Messenger messenger)
Remove a Messenger from the Message forwarding list.

Parameters:
messenger - A Messenger.
Returns:
true if the Messenger was found in the list and removed; false otherwise.
See Also:
Add_Forwarding(Messenger)

Forwarding_Messenger

public Messenger Forwarding_Messenger(String address)
Get the Messenger associated with a forwarding address.

Parameters:
address - A Messenger (@link #Address() address}. If null null is returned.
Returns:
A Messenger, or null if the address does not match that of any Messenger in the forward Messenger list.
See Also:
Add_Forwarding(Messenger)

Forwarding_Messengers

public Message Forwarding_Messengers()
Get the identities of all Messengers in the forwarding list.

Returns:
A FORWARDING_MESSENGERS_PARAMETER_NAME Message containing the identities of all the Messengers in the forwarding list. This will be null if the forwarding list is empty.

Messages_Sent

public long Messages_Sent()
Get the number of Messages successfully sent.

Returns:
The number of Messages successfully sent.

Message_Bytes_Sent

public long Message_Bytes_Sent()
Get the number of message bytes sent.

Message bytes include the message transmission label and the message body content.

Returns:
The total number of message packet bytes sent.

Messages_Sent_Dropped

public long Messages_Sent_Dropped()
Get the number of Messages that could not be sent.

Returns:
The number of Messages that could not be sent because the output was shutdown.

Messages_Sent_Corrupted

public long Messages_Sent_Corrupted()
Get the number of Messages to be sent that had content for which a PVL representation could not be generated.

Returns:
The number of Messages that could not be sent because the content was corrupted.

Messages_Received

public long Messages_Received()
Get the number of Messages successfully received.

Returns:
The number of Messages successfully received.

Message_Bytes_Received

public long Message_Bytes_Received()
Get the number of message bytes received.

Message bytes include the message transmission label and the message body content.

Returns:
The total number of message packet bytes received.

Messages_Received_Dropped

public long Messages_Received_Dropped()
Get the number of Messages that were dropped becasue they could not be completely received.

Returns:
The number of Messages that were dropped due to input shutdown before the message was completely received.

Messages_Received_Corrupted

public long Messages_Received_Corrupted()
Get the number of Messages received that were corrupted in transmission.

Returns:
The number of Messages that were received but their PVL content could not be correctly parsed.

Messages_Unforwardable

public long Messages_Unforwardable()
Get the number of Messages that could not be forwarded.

Returns:
The number of Messages that could not be forwarded due to an IOException.

Error_Condition

public Exception Error_Condition()
Get the most recent error exception.

Returns:
The Exception that most recently occured during while attempting to send or receive a message. This will be null if no error condition has occurred since the Messenger was constructed or the last reset of the error condition.

Reset_Error_Condition

public Messenger Reset_Error_Condition()
Clear the most recent error condition.

Returns:
This Messenger.
See Also:
Error_Condition()

Default_Buffer_Increment

public static int Default_Buffer_Increment(int amount)
Set the default size to use for the read buffer increment.

This value is only used when a Messenger is constructed and when a specified read buffer increment is to be set to the default value.

Parameters:
amount - The size, in bytes, of the default read buffer increment.
Returns:
The previous read buffer increment amount.
See Also:
Buffer_Increment(int)

Default_Buffer_Increment

public static int Default_Buffer_Increment()
Get the current default read buffer increment amount.

Returns:
The current default read buffer increment amount.

Buffer_Increment

public Messenger Buffer_Increment(int amount)
Set the read buffer increment amount.

The read buffer holds the message packet for a message that has been received until the message is delivered or forwarded.

While a message packet is being read from the communication channel if the read buffer is found to have insufficient space for the message packet content being read the buffer capacity is increased by to the amount of space required rounded up to the next buffer increment amount.

If a buffer shrink is pending it will remain pending after the new buffer increment is set.

Parameters:
amount - The read buffer increment amount. This will not be allowed to be less than the MINIMUM_BUFFER_SIZE. If the specified amount is less than or equal to zero the default buffer increment is used.

Buffer_Increment

public int Buffer_Increment()
Get the read buffer increment amount.

Returns:
The read buffer increment amount.

Buffer_Capacity

public int Buffer_Capacity()
Get the capacity of the read buffer.

Returns:
The capacity of the read buffer.
See Also:
Shrink_Buffer()

Shrink_Buffer

public Messenger Shrink_Buffer()
Shrink the read buffer size.

When the next Message is read the size of the read buffer will be reduced to the minimum capacity to hold the Message. This capacity will be the Message label and content size rounded up to the next multiple of the buffer size increment. The buffer shrink will not be done again until this method is called again.

N.B.: In general, the read buffer should be allowed to expand to the maximum size for messages to be read after which point the buffer will no longer need to be reallocated (a relatively expensive operation). However, if an extraordinarily large message has been read it might be beneficial to shrink the buffer to free the excess storage.

Returns:
This Messenger.
See Also:
Buffer_Capacity()

Listening_for_Messages

public boolean Listening_for_Messages()
Test if the Messenger thread is running and marked to continue listening for messages.

To only test if the Messenger thread is running use Thread.isAlive().

Returns:
If true the Messenger thread is running and marked to continue listening for messages. If false the Messenger thread will stop listening for messages after the current Message is handled, or the next Message is handled if the Messenger thread is waiting for an incoming message.
See Also:
Stop_Listening_for_Messages()

Listen_for_Messages

public Thread Listen_for_Messages()
Start the Messenger thread listening for messages.

Asynchronous message receipt can only occur when this Messenger has an employer to whom the messages will be delivered.

If the message listener thread is not running and the Messenger is connected it will be started.

Returns:
The message listenter Thread. This will be null only if the Messenger is not connected.
Throws:
IllegalStateException - If the Messenger was constructed without an employer.
See Also:
Listening_for_Messages(), Stop_Listening_for_Messages()

Stop_Listening_for_Messages

public boolean Stop_Listening_for_Messages()
Flag the Messenger thread to stop listening for messages.

The Messenger thread is flagged to stop listening for messages after the current Message is handled, or the next Message is handled if the Messenger thread is currently waiting for an incoming message.

N.B.: The Messenger thread, if it is running, will not stop immediately. To wait for the Messenger thread to stop:

    messenger.Stop_Listening_for_Messages ();
    while (messenger.isAlive ())
        {
        try {messenger.join ())
        catch (InterruptedException e) {}
        }

Returns:
true if the Messenger has stopped listing for messages; false if the Messenger has not yet stopped.

Message_Listeners

public static ThreadGroup Message_Listeners()
Get the group of all message listener threads.

When a Messenger begins to asynchronously listen for messages it runs a Thread which excecutes a loop that waits for a message packet to be read and then routes the packet for delivery. The message listener thread will only stop on its own if a) after handling a message that has been read, the thread has been flagged to stop; b) the communication input channel has been shutdown; or c) an unexpected exception occurs.

Each message listener thread is placed in a ThreadGroup named "Messengers" that is used by all Messengers. The name of each message listener thread in the group is the Messenger's address.

Returns:
The ThreadGroup containing all the message listener threads in use by Messengers.

Send

public void Send(Message message)
          throws IOException,
                 PVL_Exception
Send a Message over the communication channel.

The message label routing information is updated. Then the Message is converted to a message packet which is sent to the output channel. After successfully sending the message the count of (@link #Messages_Sent() messages sent} is incremented and the count of message bytes sent is updated.

If the message can not be sent because the content can not be represented by PVL syntax the count of corrupted send messages is incremented and the error condition is noted.

Parameters:
message - The Message to be sent. If null or empty, nothing is sent.
Throws:
EOFException - If the output communication channel was found to be shutdown before attempting to send the message.
IOException - If there was a problem while writing the message to the communication channel.
PVL_Exception - If the message content contains parameters that can not be represented by the Message PVL syntax.

Send_Packet

protected void Send_Packet(Message message_label,
                           ByteBuffer content)
                    throws IOException
Send the message packet.

If the content is null or has nothing remaining, nothing is done.

If the output channel has been shutdown the count of send messages dropped is incremented, the error condition is set to an EOFException, and the Messenger is put in the done state.

If the message label is not null its routing information is updated and then converted to a packet label String which is wrapped in a ByteBuffer that is added to a message content buffers array. If the message label is null the packet content contains the entire message, including the message label, as provided by the message packet generator.

The content ByteBuffer is added to a message message content buffers array and the sequence of buffers is written to the output channel. This is done as a single operation, rather than writing the message label separately from the message body content, to ensure that the message will not be inadvertently interleaved with another message being written to the same ouput channel at the same time. The count of messages sent is incremented and the count of message bytes sent is updated.

If the message packet can not be transmitted the count of send messages dropped is incremented, the error condition is set to the exception that occured, and the Messenger is put in the done state.

N.B.: The message routing address lists are only updated if a message label is provided. Otherwise the content buffer is presumed to already contain the correct routing information.

Parameters:
message_label - A Message containing the message start synchronization sequence and the routing parameters. This may be null if the content contains the entire message including the message label.
content - A ByteBuffer containing the message packet content. If null or empty nothing will be done.
Throws:
EOFException - If the output communication channel was found to be shutdown before attempting to send the message.
IOException - If there was a problem while writing the message to the communication channel.

Update_Send_Routing

protected void Update_Send_Routing(Message message)
Update the message send routing information of a Message.

If the message is not null and the last address on its route-to list is the same as this Messenger's address it is (@link Message#Pop_To() removed from the route-to list} and added to the route-from list.

N.B.: This method is only intended for use when sending a message. Message delivery and synchronous receive is effectively "sending" the message to the Messenger employer.

Parameters:
message - The Message to have its routing information updated. If null, nothing is done.

Receive

public Message Receive(int timeout)
                throws IllegalStateException,
                       IOException,
                       PVL_Exception
Receive a message synchronously.

If this Messenger is currently asynchronously listening for messages an IllegalStateException will be thrown. The Messenger must first be flagged to stop listening and have actually stopped.

A message packet is read from the input channel. Its routing information is updated and the packet content is used to set the message content.

Parameters:
timeout - The maximum amount of time, in seconds, to wait for message arrival. If less than or equal to zero the wait will be indefinate.
Returns:
The Message that was received. This will not be null.
Throws:
IllegalStateException - If this Messenger is currently asynchronously listening for messages.
IOException - If a message could not be read. There are various possible forms of this exception:

SocketTimeoutException
The timeout expired.
EOFException
The input channel was shutdown or closed.
Other
Read error on the input channel.
PVL_Exception - If the message content can not be parsed or is not valid.

Receive

public Message Receive()
                throws IllegalStateException,
                       IOException,
                       PVL_Exception
Receive a message synchronously.

This is the same as receiving a message with no timeout.

Returns:
The Message that was received. This will not be null.
Throws:
IllegalStateException - If this Messenger is currently asynchronously listening for messages.
IOException - If a message could not be read.
PVL_Exception - If the message content can not be parsed or is not valid.

Read_Packet

protected Message Read_Packet(int timeout)
                       throws IOException,
                              PVL_Exception
Read a Message packet from the communication channel.

A Message packet is a tentative Message: A packet Message contains only the label section of the transmitted message; the message body content remains unparsed in the read buffer. The label section must start with the message start synchronization sequence:

  1. Message.START_MARKER
  2. Message.START_MARKER_DELIMITER
  3. Up to MAX_LABEL_LENGTH_DIGITS
  4. Message.START_MARKER_END

The input communication channel is read one byte/character at a time until the entire message start synchnronization sequence has been recognized. Any unexpected character value will cause the scan for the message start synchronization sequence to start again from the beginning. The digits in the start synchronization sequence represent the size of the message label section that follows. This many bytes are read from the input channel and used to construct a message. This message label has its route-to list and route-from list set from the ROUTE_TO_PARAMETER_NAME Value and ROUTE_FROM_PARAMETER_NAME Value, respectively, if they are present. The content amount of the message label is obtained and this many bytes are read from the input channel. The message is invalid if the content amount can not be obtained from the message label.

Though the content section of the message will have been read, it remains unparsed in the Read_Buffer with its position set to the beginning of the content data and its limit set to the end of message data. If the message packet is to be forwarded there is no need to parse the message content section; otherwise the Receive method will replace the Message with the content section to generate the Message to be delivered.

N.B.: If the label section can not be parsed the count of corrupted messages will be incremented and then it will not be possible to read the content section because its size is unknown. In this case message synchronization will creep over the remaining unread message to locate the beginning of the next message.

The count of messages received is incremented when an entire Message has been received. The count of message bytes received is updated as they are read. Thus the number of bytes received includes corrupted messages.

N.B.: It is the responsibility of the user to call the Done method if an exception is thrown. Done is not called here because this method is expected to be called within a block synchronized on the Read_Buffer and the Done method should not be called within this sychnronized block since the delivery of the Done Message could result in an Employer's delivery Thread calling Done again which would result in a deadlock.

Parameters:
timeout - The amount of time (seconds) to wait for the arrival of the message before a timeout exception will occur.
Returns:
A Messsage with message label section parameters with the To and From data members having been set from these parameters.
Throws:
IOException - If there was a problem reading the message.
PVL_Exception - If the label section could not be parsed as valid PVL syntax.

Route_Packet

protected void Route_Packet(Message message,
                            ByteBuffer content)
                     throws PVL_Exception
Route a message packet to a recipient.

The packet's next route-to address examined. If there is an address (the route-to list was not empty) and the address matches the address of this Messenger then the next address on the packet's route-to list, if there is one, is compared with the addresses of the forwarding Messengers list. If the address is for a forwarding Messenger it is used to send the packet.

If the address removed from the route-to list is not for this Messenger (an empty route-to list is implicitly addressed to this Messenger) or a forwarding address is found that does not match the address of the forwarding Messenger, the message is bounced back to this Messenger's client. The bounce message contains an UNDELIVERABLE_ACTION action parameter, an EXPLANATION_PARAMETER_NAME, ROUTE_TO_PARAMETER_NAME and ROUTE_FROM_PARAMETER_NAME parameters set to the address routing of the undeliverable Message, and the message that was received as an ORIGINAL_MESSAGE_PARAMETER_NAME. If message forwarding failed an attempt will also be made to bounce the message back to this Messenger's client; an EXCEPTION_PARAMETER_NAME is included in this case that provides the detail message from the exception that occurred.

If the packet is neither forwarded nor bounced the Message contains is delivered to this Messenger's employer.

If the content could not be parsed as valid PVL the corrupted messages count is incremented and the error condition is noted.

Parameters:
message - A received Message label. If null nothing is done.
content - A ByteBuffer holding the message content.
Throws:
PVL_Exception - If the content could not be parsed for Message delivery.

Deliver

protected void Deliver(Message message)
Deliver a Message locally.

If the Message contains an ADDRESS_PARAMETER_NAME ACTION_PARAMETER_NAME value it is changed to MESSENGER_ADDRESS_PARAMETER_NAME and sent as a reply to the source of the Message. In effect this special Message is delivered to the Messenger which simply replies so the sender can it can obtain the address routing information for this Messenger.

If the Messenger has an employer all non-Address Messages are delivered to it. The address of this Messenger is added to the Message's route-from list and the route-to list is emptied. The employer's Message_Delivered method is invoked with a Message_Delivered_Event containing the Message obtained by this Messenger. N.B.: The delivery of Message is synchronized on the employer to prevent it changing while the during delivery; do not attempt changing the employer in the thread that receives the Message delivery or a deadlock will occur.

N.B.: If the Messenger has been constructed without an employer, and one has not been assigned, then obviously no Message can be delivered.

Parameters:
message - The Message to be delivered to the employer. If null, nothing is done.

Done

public boolean Done()
Force the Messenger to close its client communication channel.

Input and output for the socket of the client communication channel is shutdown if it not already done. The channel is then closed if it was open.

N.B.: No Done Message notification is delivered to the employer.

Returns:
true if the Messenger was not done when the method was called (this call caused the communication channel I/O to be shutdown and/or closed); false if the communication channel had already been shutdown and closed for any reason.
See Also:
Done(String, Exception)

Done

public void Done(String explanation,
                 Exception exception)
Deliver a Done Message to the employer and close its communication channel.

N.B.: The Done Message is delivered before the request to close the communication channel occurs; the communicaiton channel may already have been closed by an external event, however.

N.B.: Only one Done Message will ever be delivered by each Messenger object.

Parameters:
explanation - If non-null an EXPLANATION_PARAMETER_NAME is included in the Done Message with the explanation text as its value.
exception - If non-null an EXCEPTION_PARAMETER_NAME is included in the Done Message that provides the exception detail message as its value.
See Also:
Done(), Is_Connected()

Done

public void Done(String explanation)
Force the Messenger to close its communication channel and deliver a Done Message.

Parameters:
explanation - If non-null an EXPLANATION_PARAMETER_NAME is included in the Done Message with the explanation text as its value.
See Also:
Done(String, Exception)

Connect

public static SocketChannel Connect(SocketAddress address)
                             throws IOException,
                                    IllegalArgumentException
Connect to a SocketAddress.

A new SocketChannel is opened and its socket set to SO_REUSEADDR mode (which allows the socket to be bound to the address port even if it is currently in a closed connection timeout state). An attempt is then made using the socket to connect to the specified address with a connection timeout of Connect_Timeout() seconds. If the connection fails for any reason the SocketChannel is closed and the connection attempt is repeated. After MAX_RECONNECT_ATTEMPTS a failure to connect will throw the last exception that cause the connection to fail.

Parameters:
address - The SocketAddress to which to connect.
Returns:
A connected SocketChannel.
Throws:
IllegalArgumentException - If the address is null.
IOException - If there was a problem establishing the connection.

Configure_Socket

public static void Configure_Socket(Socket socket)
                             throws IOException
Configures a Socket.

The socket options are set to:

N.B.: The socket must be configured before it is conneected for the socket options to be effective.

Parameters:
socket - The socket to be configured.
Throws:
IOException

PIRL

Copyright (C) \ 2003-2009 Bradford Castalia, University of Arizona