Skip to content
Ian Clarke edited this page Jun 21, 2014 · 18 revisions

Tahrir's messaging framework is responsible for sending, receiving, and responding to messages transmitted between peers across the network.

Tahrir's approach to messaging, like all of Tahrir's building blocks, is intended to make it as easy as possible for more sophisticated functionality to be built on-top.

To achieve this, as with Tahrir's serialization mechanism, Tahrir is unafraid to make full-use of Java's reflection functionality, to make life as easy as possible for users of the messaging framework.

Tahrir's approach is similar to the RPC implementation used in GWT. Dynamic proxy classes are used to allow messages to be sent to remote Tahrir nodes just by calling a method, as if it was a local object.

We do impose some restrictions on the types of methods that can be called, for example, they must be asynchronous and and therefore they may not return values. This avoids any requirement to have threads waiting around for responses. Instead, a remote Tahrir node may respond by calling a method on the local node. It is possible that this will change in future.

Usage

Let's assume that we have the following cast of characters:

  • iface, a UdpNetworkInterface - this class is responsible for sending and receiving messages on a specific UDP port
  • trc, a TrRemoteConnection - this class allows reliable sending and receiving of messages from a remote peer (typically over an encrypted UDP channel)
  • trn, a TrNet - this class wraps iface and trc in our RPC implementation

Let's create a simple TrSession with a single method that can be called by remote nodes:

public static interface IncrementSession extends TrSession {
		public void sendCount(int param);
}

public static class IncrementSessionImpl extends TrSessionImpl implements ImcrementSession {

	public IncrementSessionImpl(final Integer sessionId, final TrNode<?> node) {
		super(sessionId, node);
	}

	public void sendCount(final int param) {
		System.out.println(node.networkInterface + " testMethod(" + param + ")");
		if (param < 10) {
			final IncrementSession remote = getTrNet()
                            .getOrCreateRemoteSession(IncrementSession.class, getSender(), 1.0);
			remote.sendCount(param + 1);
 		}
	}
}
Clone this wiki locally