public class MessageDispatcher extends java.lang.Object implements Receiver, java.io.Serializable
NetworkNode
identifier is created.
After the initialization, messages can be sent to another host, where
the MessageDispatcher
is running using sendMessage
method.
This method sends a Message
to the destination MessageDispatcher
, addressed
by its NetworkNode
.
If a multicast group has been initialized, it is also possible to send a message
to all participants, i.e. no destination is given.
It is also possible to wait for a ReplyMessage
, i.e. we expect another message to return
in response to a message sent by us. This can be done through sendMessageWaitReply
method, which returns an instance of ReplyReceiver
associated with the sent message - see its
documentation for detailed info on how to get the received reply messages.
The waiting mechanism allows also more complex scenarios, when multiple hosts are involved:
The method that waits for results ensures the completeness of the answer, even if the message was
sent to several network nodes that forward it (either replying or not) to another network nodes and even
if the message pathes contain cycles.
On the other hand, the dispatcher allows to receive messages. The replies are received and passed to
an associated ReplyReceiver automatically. For normal messages, we can register a message receiver
.
Once a message is received on any socket, it is passed to every registered receiver through its
acceptMessage
until true is returned. Thus the first
receiver, that accepts the message stops the traversal. If there is no receiver that accepts the provided
message, a warning is logged.
NetworkNode
,
Message
,
ReplyMessage
,
ReplyReceiver
,
Serialized FormModifier and Type | Field and Description |
---|---|
protected static java.net.InetAddress |
BROADCAST_GROUP
Multicast group IP address constant
|
protected java.net.MulticastSocket |
broadcastSocket
UDP multicast socket for broadcast communication
It is null if broadcast is not initialized.
|
protected static java.util.logging.Logger |
log
Logger
|
protected NetworkNode |
ourNetworkNode
Identification of this network node
|
protected java.net.ServerSocket |
tcpSocket
TCP socket for communication
|
protected MessageDispatcher |
topMessageDispatcher
Top most message dispatcher in the hierarchy
|
protected java.net.DatagramSocket |
udpSocket
UDP socket for communication
|
Constructor and Description |
---|
MessageDispatcher()
Creates a new instance of MessageDispatcher with automatically assigned port (decided by OS).
|
MessageDispatcher(int port)
Creates a new instance of MessageDispatcher with specified TCP/UDP port.
|
MessageDispatcher(int port,
int broadcastPort)
Creates a new instance of MessageDispatcher with specified TCP/UDP and broadcast ports.
|
MessageDispatcher(MessageDispatcher parentDispatcher,
int nodeID)
Creates a new server instance of MessageDispatcher connected to a higher level dispatcher.
|
MessageDispatcher(NetworkNode localAddress)
Creates a new instance of MessageDispatcher with specified TCP/UDP port.
|
MessageDispatcher(NetworkNode localAddress,
int broadcastPort)
Creates a new instance of MessageDispatcher with specified TCP/UDP and broadcast ports.
|
MessageDispatcher(java.lang.String localHost,
int port)
Creates a new instance of MessageDispatcher with specified TCP/UDP port.
|
MessageDispatcher(java.lang.String localHost,
int port,
int broadcastPort)
Creates a new instance of MessageDispatcher with specified TCP/UDP and broadcast ports.
|
Modifier and Type | Method and Description |
---|---|
boolean |
acceptMessage(Message msg,
boolean allowSuperclass)
Offers a message to this message dispatcher, i.e. run through the dispatcher's list
of registered receivers and offer the message to them.
|
void |
closeSockets()
Close all opened communication sockets and disable this dispatcher.
|
boolean |
deregisterReceiver(Receiver receiver)
Remove a previously registered receiver.
|
int |
getBroadcastPort()
Returns the broadcast port number if created or zero if broadcast is not initialized by this dispatcher.
|
protected Message |
getMessageFromStream(java.io.ObjectInputStream stream)
Unpacks a message from the byte stream.
|
NetworkNode |
getNetworkNode()
Returns the network node identification of this message dispatcher.
|
protected void |
putMessageIntoStream(Message msg,
java.io.ObjectOutputStream stream,
NetworkNode destinationNode)
Packs the provided message into byte stream.
|
protected void |
receiveMessage(Message msg)
Process a message received through sockets.
|
void |
registerReceiver(Receiver receiver)
Register a message receiver.
|
NetworkNode |
replyMessage(ReplyMessage msg)
Send the reply message, i.e. send the message to its original sender node.
|
void |
sendMessage(Message msg)
Send the message to all network nodes (that are listening for broadcast on the same port).
|
void |
sendMessage(Message msg,
java.util.Collection<NetworkNode> nodes)
Send the message to multiple network nodes.
|
void |
sendMessage(Message msg,
java.util.Collection<NetworkNode> nodes,
boolean willNotReply)
Send the message to multiple network nodes.
|
void |
sendMessage(Message msg,
NetworkNode node)
Send the message to the specified network node.
|
void |
sendMessage(Message msg,
NetworkNode node,
boolean willNotReply)
Send the message to the specified network node.
|
<E extends ReplyMessage> |
sendMessageWaitReply(Message msg,
java.lang.Class<E> replyMessageClass,
boolean removeOnAccept,
java.util.Collection<NetworkNode> nodes)
Send the message to multiple network nodes and wait for the replies.
|
<E extends ReplyMessage> |
sendMessageWaitReply(Message msg,
java.lang.Class<E> replyMessageClass,
boolean removeOnAccept,
NetworkNode node)
Send the message to the specified network node and wait for the replies.
|
<E extends ReplyMessage> |
sendMessageWaitReply(Message msg,
java.lang.Class<E> replyMessageClass,
java.util.Collection<NetworkNode> nodes)
Send the message to multiple network nodes and wait for the replies.
|
<E extends ReplyMessage> |
sendMessageWaitReply(Message msg,
java.lang.Class<E> replyMessageClass,
NetworkNode node)
Send the message to the specified network node and wait for the replies.
|
ReplyReceiver<? extends ReplyMessage> |
sendMessageWaitReply(Message msg,
java.util.Collection<NetworkNode> nodes)
Send the message to multiple network nodes and wait for the replies.
|
ReplyReceiver<? extends ReplyMessage> |
sendMessageWaitReply(Message msg,
NetworkNode node)
Send the message to the specified network node and wait for the replies.
|
<E extends ReplyMessage> |
sendMessageWaitSingleReply(Message msg,
java.lang.Class<E> replyMessageClass,
NetworkNode node)
Send the message to a network node and wait for a single reply.
|
<E extends ReplyMessage> |
sendMessageWaitSingleReply(Message msg,
java.lang.Class<E> replyMessageClass,
NetworkNode node,
long timeout)
Send the message to a network node and wait for a single reply.
|
protected static final java.net.InetAddress BROADCAST_GROUP
protected static final java.util.logging.Logger log
protected final java.net.DatagramSocket udpSocket
protected final java.net.ServerSocket tcpSocket
protected final java.net.MulticastSocket broadcastSocket
protected final NetworkNode ourNetworkNode
protected final MessageDispatcher topMessageDispatcher
public MessageDispatcher() throws java.io.IOException
java.io.IOException
- if there was error when opening communication socketspublic MessageDispatcher(int port) throws java.io.IOException
port
- the TCP/UDP port used for communication.java.io.IOException
- if there was error when opening communication socketspublic MessageDispatcher(int port, int broadcastPort) throws java.io.IOException
port
- the TCP/UDP port used for communicationbroadcastPort
- the UDP port used for sending and receiving broadcastsjava.io.IOException
- if there was error when opening communication socketspublic MessageDispatcher(java.lang.String localHost, int port) throws java.io.IOException
localHost
- the local IP address to bind the communication toport
- the TCP/UDP port used for communicationjava.io.IOException
- if there was error when opening communication socketspublic MessageDispatcher(java.lang.String localHost, int port, int broadcastPort) throws java.io.IOException
localHost
- the local IP address to bind the communication toport
- the TCP/UDP port used for communicationbroadcastPort
- the UDP port used for sending and receiving broadcastsjava.io.IOException
- if there was error when opening communication socketspublic MessageDispatcher(NetworkNode localAddress) throws java.io.IOException
localAddress
- local address to bind the TCP/UDP communication tojava.io.IOException
- if there was error when opening communication socketspublic MessageDispatcher(NetworkNode localAddress, int broadcastPort) throws java.io.IOException
localAddress
- local address to bind the TCP/UDP communication tobroadcastPort
- the UDP port used for sending and receiving broadcastsjava.io.IOException
- if there was error when opening communication socketspublic MessageDispatcher(MessageDispatcher parentDispatcher, int nodeID)
parentDispatcher
- the higher level dispatcher this instance is connected tonodeID
- the sub-identification of this dispatcher for the higher levelpublic final int getBroadcastPort()
public final NetworkNode getNetworkNode()
public void closeSockets() throws java.io.IOException
java.io.IOException
- if the sockets are no longer opened or another error occurs at OS levelpublic void sendMessage(Message msg, NetworkNode node) throws java.io.IOException
msg
- the message to sendnode
- the destination network nodejava.io.IOException
- if the communication failed, e.g. the destination node cannot be reached, etc.public void sendMessage(Message msg, java.util.Collection<NetworkNode> nodes) throws java.io.IOException
msg
- the message to sendnodes
- the list of destination network nodesjava.io.IOException
- if the communication failed, e.g. the destination node cannot be reached, etc.public void sendMessage(Message msg, NetworkNode node, boolean willNotReply) throws java.io.IOException
msg
- the message to sendnode
- the destination network nodewillNotReply
- if this flag is true, this node will not send any repliesjava.io.IOException
- if the communication failed, e.g. the destination node cannot be reached, etc.public void sendMessage(Message msg, java.util.Collection<NetworkNode> nodes, boolean willNotReply) throws java.io.IOException
msg
- the message to sendnodes
- the list of destination network nodeswillNotReply
- if this flag is true, this node will not send any repliesjava.io.IOException
- if the communication failed, e.g. the destination node cannot be reached, etc.public void sendMessage(Message msg) throws java.io.IOException
msg
- the message to sendjava.io.IOException
- if the communication failed, e.g. the broadcast is not initializedpublic NetworkNode replyMessage(ReplyMessage msg) throws java.io.IOException
msg
- the reply message to sendjava.io.IOException
- if the communication failed, e.g. the broadcast is not initializedpublic <E extends ReplyMessage> ReplyReceiver<E> sendMessageWaitReply(Message msg, java.lang.Class<E> replyMessageClass, boolean removeOnAccept, java.util.Collection<NetworkNode> nodes) throws java.io.IOException
The returned ReplyReceiver can be used to block until all replies are gathered or to control
the process of waiting. It is also used to retrieve the list of received replies (instances of ReplyMessage
).
Note that the receiver is registered automatically and unregistered when all the expected reply messages
arrive. The removal can be postponed until the ReplyReceiver.getReplies(long)
is called
(the removeOnAccept
is false), which is suitable if this method
is called several times to send a message to multiple nodes. In that case, the same
receiver is returned from all the calls and can be used afterwards to gather all
reply messages.
E
- the type of reply message to wait formsg
- the message to sendreplyMessageClass
- the reply messages class to wait for (other messages are ignored even if the message ID matches)removeOnAccept
- flag that controls whether the returned receiver is removed
from the waiting list when the last message arrives (true)
or when the getReplies is called (false)nodes
- the list of destination network nodesjava.io.IOException
- if the communication failed, e.g. the destination node cannot be reached, etc.public <E extends ReplyMessage> ReplyReceiver<E> sendMessageWaitReply(Message msg, java.lang.Class<E> replyMessageClass, boolean removeOnAccept, NetworkNode node) throws java.io.IOException
The returned ReplyReceiver can be used to block until all replies are gathered or to control
the process of waiting. It is also used to retrieve the list of received replies (instances of ReplyMessage
).
Note that the receiver is registered automatically and unregistered when all the expected reply messages
arrive. The removal can be postponed until the ReplyReceiver.getReplies(long)
is called
(the removeOnAccept
is false), which is suitable if this method
is called several times to send a message to multiple nodes. In that case, the same
receiver is returned from all the calls and can be used afterwards to gather all
reply messages.
E
- the type of reply message to wait formsg
- the message to sendreplyMessageClass
- the reply messages class to wait for (other messages are ignored even if the message ID matches)removeOnAccept
- flag that controls whether the returned receiver is removed
from the waiting list when the last message arrives (true)
or when the getReplies is called (false)node
- the destination network nodejava.io.IOException
- if the communication failed, e.g. the destination node cannot be reached, etc.public <E extends ReplyMessage> ReplyReceiver<E> sendMessageWaitReply(Message msg, java.lang.Class<E> replyMessageClass, java.util.Collection<NetworkNode> nodes) throws java.io.IOException
The returned ReplyReceiver can be used to block until all replies are gathered or to control
the process of waiting. It is also used to retrieve the list of received replies (instances of ReplyMessage
).
Note that the receiver is registered automatically and unregistered when all the expected reply messages
arrive and the ReplyReceiver.getReplies(long)
is called.
E
- the type of reply message to wait formsg
- the message to sendreplyMessageClass
- the reply messages class to wait for (other messages are ignored even if the message ID matches)nodes
- the list of destination network nodesjava.io.IOException
- if the communication failed, e.g. the destination node cannot be reached, etc.public <E extends ReplyMessage> ReplyReceiver<E> sendMessageWaitReply(Message msg, java.lang.Class<E> replyMessageClass, NetworkNode node) throws java.io.IOException
The returned ReplyReceiver can be used to block until all replies are gathered or to control
the process of waiting. It is also used to retrieve the list of received replies (instances of ReplyMessage
).
Note that the receiver is registered automatically and unregistered when all the expected reply messages
arrive and the ReplyReceiver.getReplies(long)
is called.
E
- the type of reply message to wait formsg
- the message to sendreplyMessageClass
- the reply messages class to wait for (other messages are ignored even if the message ID matches)node
- the destination network nodejava.io.IOException
- if the communication failed, e.g. the destination node cannot be reached, etc.public ReplyReceiver<? extends ReplyMessage> sendMessageWaitReply(Message msg, NetworkNode node) throws java.io.IOException
The returned ReplyReceiver can be used to block until all replies are gathered or to control
the process of waiting. It is also used to retrieve the list of received replies (instances of ReplyMessage
).
Note that the receiver is registered automatically and unregistered when all the expected reply messages
arrive.
msg
- the message to sendnode
- the destination network nodejava.io.IOException
- if the communication failed, e.g. the destination node cannot be reached, etc.public ReplyReceiver<? extends ReplyMessage> sendMessageWaitReply(Message msg, java.util.Collection<NetworkNode> nodes) throws java.io.IOException
The returned ReplyReceiver can be used to block until all replies are gathered or to control
the process of waiting. It is also used to retrieve the list of received replies (instances of ReplyMessage
).
Note that the receiver is registered automatically and unregistered when all the expected reply messages
arrive.
msg
- the message to sendnodes
- the list of destination network nodesjava.io.IOException
- if the communication failed, e.g. the destination node cannot be reached, etc.public <E extends ReplyMessage> E sendMessageWaitSingleReply(Message msg, java.lang.Class<E> replyMessageClass, NetworkNode node) throws java.io.IOException
E
- the type of reply message to wait formsg
- the message to sendreplyMessageClass
- the reply messages class to wait for (other messages are ignored even if the message ID matches)node
- the destination network nodejava.io.IOException
- if the communication failed, e.g. the destination node cannot be reached, etc.public <E extends ReplyMessage> E sendMessageWaitSingleReply(Message msg, java.lang.Class<E> replyMessageClass, NetworkNode node, long timeout) throws java.io.IOException, java.lang.InterruptedException
E
- the type of reply message to wait formsg
- the message to sendreplyMessageClass
- the reply messages class to wait for (other messages are ignored even if the message ID matches)node
- the destination network nodetimeout
- timeout to wait for repliesjava.io.IOException
- if the communication failed, e.g. the destination node cannot be reached, etc.java.lang.InterruptedException
- if there was no message within the specified timeout or the thread was interrupted while waitingpublic void registerReceiver(Receiver receiver)
acceptMessage
of the receiver is called whenever
a message arrives at this dispatcher. The first receiver (in the order of their registrations) that
accepts the message stops the processing.receiver
- the message receiver; see for example ThreadInvokingReceiver
or QueueInvokingReceiver
public boolean deregisterReceiver(Receiver receiver)
receiver
- a previously registered receiver that has to be removedprotected void receiveMessage(Message msg)
msg
- the message receivedpublic boolean acceptMessage(Message msg, boolean allowSuperclass)
acceptMessage
in interface Receiver
msg
- the message offered to acceptanceallowSuperclass
- First, the message is offered with allowSuperclass set to false.
If no receiver accepts it, another offering round is issued with allowSuperclass
set to true (so the receiver can relax its acceptance conditions).protected void putMessageIntoStream(Message msg, java.io.ObjectOutputStream stream, NetworkNode destinationNode) throws java.io.IOException
msg
- the message to pack to the streamstream
- the stream to pack the message intodestinationNode
- the destination network nodejava.io.IOException
- if the message cannot be serializedprotected Message getMessageFromStream(java.io.ObjectInputStream stream) throws java.io.IOException
stream
- the stream from which the message should be unpackedjava.io.IOException
- if the message cannot be deserialized