|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object PIRL.Messenger.Messenger
public class Messenger
A Messenger sends and receives Messages over a communication channel and routes received messages to their destination.
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.
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.
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.
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.
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 |
---|
public static final String ID
public static final String DATE_FORMATTING
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.
public static final SimpleDateFormat DATE_FORMAT
start time
.
DATE_FORMATTING
public static final char ADDRESS_SEGMENT_DELIMITER
address
.
protected Message Identity
identify
the Messenger by employer applications.
The content of the message is determined by the application.
public static final String IDENTITY_PARAMETER_NAME
Identity Message
.
public static final String NAME_PARAMETER_NAME
public static final String ADDRESS_PARAMETER_NAME
Identity
Message parameter set to
contain the Messenger Address.
public static final String MESSENGER_ADDRESS_PARAMETER_NAME
ACTION_PARAMETER_NAME
value sent in response to
receiving an ADDRESS_PARAMETER_NAME
action Message for
delivery
.
public static final String ROUTE_TO_PARAMETER_NAME
route-to list
.
Message.Packet_Label(int)
,
Constant Field Valuespublic static final String ROUTE_FROM_PARAMETER_NAME
route-from list
.
Message.Packet_Label(int)
,
Constant Field Valuespublic static final String ACTION_PARAMETER_NAME
public static final String FORWARDING_MESSENGERS_PARAMETER_NAME
forwarding
Messengers
identities parameter group.
public static final int MAX_LABEL_LENGTH_DIGITS
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.
DEFAULT_BUFFER_INCREMENT
,
Constant Field Valuespublic static final int MINIMUM_BUFFER_SIZE
The minimum read buffer size must allow for the Message start synchronization sequence:
Message.START_MARKER
Message.START_MARKER_DELIMITER
MAX_LABEL_LENGTH_DIGITS
Message.START_MARKER_END
DEFAULT_BUFFER_INCREMENT
public static final int DEFAULT_BUFFER_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.
public static final String UNDELIVERABLE_ACTION
ACTION_PARAMETER_NAME
value.
public static final String ORIGINAL_MESSAGE_PARAMETER_NAME
UNDELIVERABLE_ACTION
Message.
public static final String EXPLANATION_PARAMETER_NAME
public static final String EXCEPTION_PARAMETER_NAME
public static final int DEFAULT_CONNECT_TIMEOUT
connection
.
public static final int MAX_RECONNECT_ATTEMPTS
public static final int DEFAULT_CLOSE_TIME
Constructor Detail |
---|
public Messenger(Message_Delivered_Listener employer, SocketChannel client_channel) throws IllegalArgumentException
The address
and identity
are intialized.
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.
IllegalArgumentException
- If the client is null.public Messenger(Message_Delivered_Listener employer, InetSocketAddress client_address) throws IllegalArgumentException, IOException
The client address is used to connect
to the client's communication channel.
The address
and identity
are intialized.
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.
IllegalArgumentException
- If either the employer
or server is null.
IOException
- If there was a problem connecting to the
server.Messenger(Message_Delivered_Listener, SocketChannel)
public Messenger(Message_Delivered_Listener employer, String host, int port) throws IllegalArgumentException, IOException
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.
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.
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.Messenger(Message_Delivered_Listener, InetSocketAddress)
public Messenger(String host, int port) throws IllegalArgumentException, IOException
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.
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.
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.Messenger(Message_Delivered_Listener, String, int)
Method Detail |
---|
public String Address()
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
.
Message.Route_To()
,
Message.Route_From()
public long Start_Time()
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.
public Message Identity()
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.
public Messenger Identity(Message identity)
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.
identity
- A Message containing parameters that describe
the identity of this Messenger.
public String toString()
toString
in class Object
public static int Connect_Timeout()
Connect_Timeout(int)
public static void Connect_Timeout(int timeout)
timeout
- The connection timeout, in seconds. If less than one
the DEFAULT_CONNECT_TIMEOUT
will be used.Connect(SocketAddress)
public String Client_Hostname()
Host.FULL_HOSTNAME
.public int Client_Port()
N.B.: The availability of a remote port number does not
imply that the communication channel is
connected
.
public boolean Is_Connected()
A Messenger is connected if the client communication channel
is open and connected.
public SocketChannel Client_Channel()
Is_Connected()
public int Port()
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.
public Message_Delivered_Listener Employer()
Messages recieved are delivered
to the
employer if they are addressed to this Messanger or have no address.
Message_Delivered_Listener
,
Employer(Message_Delivered_Listener)
public Messenger Employer(Message_Delivered_Listener employer)
Messages recieved are delivered
to the
employer if they are addressed to this Messanger or have no address.
employer
- A Message_Delivered_Listener employer object.
IllegalArgumentException
- If the employer is null.Message_Delivered_Listener
public Messenger Add_Forwarding(Messenger messenger)
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.
messenger
- A Messenger. If null nothing is done.
Remove_Forwarding(Messenger)
,
Forwarding_Messenger(String)
public boolean Remove_Forwarding(Messenger messenger)
messenger
- A Messenger.
Add_Forwarding(Messenger)
public Messenger Forwarding_Messenger(String address)
address
- A Messenger (@link #Address() address}. If null
null is returned.
forward
Messenger list
.Add_Forwarding(Messenger)
public Message Forwarding_Messengers()
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.public long Messages_Sent()
sent
.
public long Message_Bytes_Sent()
sent
.
Message bytes include the message transmission label
and the message body content.
public long Messages_Sent_Dropped()
sent
.
public long Messages_Sent_Corrupted()
sent
that
had content for which a PVL representation could not be generated.
public long Messages_Received()
received
.
public long Message_Bytes_Received()
received
.
Message bytes include the message transmission label
and the message body content.
public long Messages_Received_Dropped()
received
.
public long Messages_Received_Corrupted()
public long Messages_Unforwardable()
forwarded
.
public Exception Error_Condition()
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.public Messenger Reset_Error_Condition()
Error_Condition()
public static int Default_Buffer_Increment(int amount)
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.
amount
- The size, in bytes, of the default read buffer increment.
Buffer_Increment(int)
public static int Default_Buffer_Increment()
public Messenger Buffer_Increment(int 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.
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.public int Buffer_Increment()
public int Buffer_Capacity()
Shrink_Buffer()
public Messenger Shrink_Buffer()
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.
Buffer_Capacity()
public boolean Listening_for_Messages()
listening for messages
.
To only test if the Messenger thread is running use Thread.isAlive()
.
Stop_Listening_for_Messages()
public Thread Listen_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.
IllegalStateException
- If the Messenger was constructed
without an employer.Listening_for_Messages()
,
Stop_Listening_for_Messages()
public boolean Stop_Listening_for_Messages()
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) {}
}
public static ThreadGroup Message_Listeners()
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
.
public void Send(Message message) throws IOException, PVL_Exception
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.
message
- The Message to be sent. If null or empty, nothing
is sent.
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.protected void Send_Packet(Message message_label, ByteBuffer content) throws IOException
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.
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.
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.protected void Update_Send_Routing(Message 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
.
message
- The Message to have its routing information updated.
If null, nothing is done.public Message Receive(int timeout) throws IllegalStateException, IOException, PVL_Exception
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
.
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.
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:
PVL_Exception
- If the message content can not be parsed or
is not valid.public Message Receive() throws IllegalStateException, IOException, PVL_Exception
This is the same as receiving a message
with no
timeout.
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.protected Message Read_Packet(int timeout) throws IOException, PVL_Exception
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:
Message.START_MARKER
Message.START_MARKER_DELIMITER
MAX_LABEL_LENGTH_DIGITS
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.
timeout
- The amount of time (seconds) to wait for the
arrival of the message before a timeout exception will occur.
IOException
- If there was a problem reading the message.
PVL_Exception
- If the label section could not be parsed as
valid PVL syntax.protected void Route_Packet(Message message, ByteBuffer content) throws PVL_Exception
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.
message
- A received Message label. If null nothing is done.content
- A ByteBuffer holding the message content.
PVL_Exception
- If the content could not be parsed for
Message delivery.protected void Deliver(Message message)
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.
message
- The Message to be delivered to the employer. If null,
nothing is done.public boolean Done()
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
.
Done(String, Exception)
public void Done(String explanation, Exception exception)
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.
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.Done()
,
Is_Connected()
public void Done(String explanation)
Done
Message.
explanation
- If non-null an EXPLANATION_PARAMETER_NAME
is included in the Done Message with the explanation text as its
value.Done(String, Exception)
public static SocketChannel Connect(SocketAddress address) throws IOException, IllegalArgumentException
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.
address
- The SocketAddress to which to connect.
IllegalArgumentException
- If the address is null.
IOException
- If there was a problem establishing the
connection.public static void Configure_Socket(Socket socket) throws IOException
The socket options are set to:
These priorities are a hint that may have no effect on the specific socket implementation being used by the system.
SO_REUSEADDR
enabled.
Allows a socket to be bound even though a previous connection is in a timeout state.
SO_KEEPALIVE
enabled.
Provide a persistent socket connection even if there is no application communication for an extended time.
SO_LINGER
enabled with a linger time of DEFAULT_CLOSE_TIME
seconds.
When the socket is closed and unsent data is queued for transmission the close will block until the data has been trasmitted or the linger time has been reached.
socket
- The socket to be configured.
IOException
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |