The Message
class represents all messages that are sent with the publish/subscribe system. Messages are immutable, meaning you need to construct a new object for every message. The Message
class provides some convenience methods for constructing new messages based on old ones. Message
implements Serializable
so that messages can be sent over the network.
A message has 4 parts:
/{orch}/{node}
. Messages addressed /*
are delivered to all supernodes. Messages addressed /*/*
are delivered to all nodes and supernodes. Messages /orch/*
are sent to all nodes in the orchestra and the orchestra's supernodes. Messages /orch
are sent to an orchestra's supernode only. Messages addressed /orch/name
are sent to a specific node in the orchestra.Important: If the node or supernode sending a message matches the destination address, it will also receive a copy of the message. For example, a node that sends a chat message to /*/*
will receive a copy of the message it sent. This is necessary to support communication between components at a given node. Clients should be aware of this and filter messages as necessary.
In brief, messages to the current node only are delivered locally, as are messages to /*/*
or /local-orch/*
.
Messages from a node with /*
or /non-local-orch
are forwarded to the supernode.
Once at the supernode, there are cases:
/local-orch/my-name
-> deliver the message locally
/non-local-orch/any
-> forward to the non-local-orch
/local-orch/name
-> forward to name
/local-orch/*
-> iterate through node list and send to each node except the originating node. Also send a copy to self except if self is the originating node.
/*/*
-> iterate through the supernode list and send to each supernode, changing the address to /remote-orch/*
. Also publish a copy to /local-orch/*
(recursively invoking case 3 (above).
Note that the decision to deliver locally and/or forward is different for nodes and supernodes. A node delivers /*/*
and /local-orch/*
to itself and forwards to the
supernode. No message comes back. A supernode does not immediately deliver /*/*
or /local-orch/*
to itself, and relies on forwarding to do it.
To support case 3 and to prevent messages getting sent back to the original sender, which would cause an infinite loop, messages need an "originator" field that is the /orch/name
of the original sender of the message.
Subscribable | |
---|---|
void subscribeTo(String topic, Subscriber sub) | Subscribes a node to a topic. All messages will be handled by the given Subscriber object |
void unsubscribeFrom(String topic, Subscriber) | Unsubscribes a node from a topic. Messages still may be handled by other Subscriber objects |
To receive messages, implement:
Subscriber | |
---|---|
void receiveMessage(Message msg) | Receives a Message object. You may handle the message any way you see fit |
To publish messages:
Publisher | |
---|---|
void publish(Message msg) | Sends a message |
To creating a message:
Message | |
---|---|
Message(long timestamp, String address, String topic, String body) | Fill in the fields as described in the above description of messages |