eneter.messaging.endpoints.typedmessages
Class MultiTypedMessagesFactory

java.lang.Object
  extended by eneter.messaging.endpoints.typedmessages.MultiTypedMessagesFactory
All Implemented Interfaces:
IMultiTypedMessagesFactory

public class MultiTypedMessagesFactory
extends java.lang.Object
implements IMultiTypedMessagesFactory

Factory to create multi-typed message senders and receivers. The following example shows how to send and receive messages:
Implementation of receiver (service):

 public class Program
 {
     public static class MyRequestMessage
     {
         public double Number1;
         public double Number2;
     }
  
public static void main(String[] args) { try { // Create multi-typed receiver. IMultiTypedMessagesFactory aFactory = new MultiTypedMessagesFactory(); IMultiTypedMessageReceiver aReceiver = aFactory.createMultiTypedMessageReceiver();
// Register message types which can be processed. aReceiver.registerRequestMessageReceiver(myIntegerHandler, Integer.class); aReceiver.registerRequestMessageReceiver(myMyRequestMessageHandler, MyRequestMessage.class);
// Attach input channel and start listening e.g. using TCP. IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory(); IDuplexInputChannel anInputChannel = aMessaging.createDuplexInputChannel("tcp://127.0.0.1:8033/"); aReceiver.attachDuplexInputChannel(anInputChannel);
System.out.println("Service is running. Press ENTER to stop."); new BufferedReader(new InputStreamReader(System.in)).readLine();
// Detach input channel to stop the listening thread. aReceiver.detachDuplexInputChannel(); } catch (Exception err) { EneterTrace.error("Service failed.", err); } }
private static void onIntegerMessage(Object eventSender, TypedRequestReceivedEventArgs<String> e) { int aNumber = e.getRequestMessage();
// Calculate factorial. int aResult = 1; for (int i = 1; i <= aNumber; ++i) { aResult *= i; }
System.out.println(aNumber + "! =" + aResult);
// Send back the result. IMultiTypedMessageReceiver aReceiver = (IMultiTypedMessageReceiver)eventSender; try { aReceiver.sendResponseMessage(e.getResponseReceiverId(), aResult, Integer.class); } catch (Exception err) { EneterTrace.error("Failed to send the response message.", err); } }
private static void onMyReqestMessage(Object eventSender, TypedRequestReceivedEventArgs<MyRequestMessage> e) { MyRequestMessage aRequestMessage = e.getRequestMessage();
double aResult = aRequestMessage.Number1 + aRequestMessage.Number2;
System.out.println(aRequestMessage.Number1 + " + " + aRequestMessage.Number2 + " = " + aResult);
// Send back the message. IMultiTypedMessageReceiver aReceiver = (IMultiTypedMessageReceiver)eventSender; try { aReceiver.sendResponseMessage(e.getResponseReceiverId(), aResult, Double.class); } catch (Exception err) { EneterTrace.error("Failed to send the response message.", err); } }
private static EventHandler<TypedRequestReceivedEventArgs<Integer>> myIntegerHandler = new EventHandler<TypedRequestReceivedEventArgs<Integer>>() { @Override public void onEvent(Object sender, TypedRequestReceivedEventArgs<Integer> e) { onStringMessage(sender, e); } };
private static EventHandler<TypedRequestReceivedEventArgs<MyRequestMessage>> myMyRequestMessageHandler = new EventHandler<TypedRequestReceivedEventArgs<MyRequestMessage>>() { @Override public void onEvent(Object sender, TypedRequestReceivedEventArgs<MyRequestMessage> e) { onMyReqestMessage(sender, e); } };
}
Implementation of sender (client):
 public class Program
 {
     public static class MyRequestMessage
     {
         public double Number1;
         public double Number2;
     }
  
public static void main(String[] args) { // Create multi-typed sender. IMultiTypedMessagesFactory aFactory = new MultiTypedMessagesFactory(); ISyncMultitypedMessageSender aSender = aFactory.createSyncMultiTypedMessageSender();
try { // Attach output channel and be able to communicate with the service. IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory(); IDuplexOutputChannel anOutputChannel = aMessaging.createDuplexOutputChannel("tcp://127.0.0.1:8033/"); aSender.attachDuplexOutputChannel(anOutputChannel);
// Request to calculate two numbers. MyRequestMessage aRequestMessage = new MyRequestMessage(); aRequestMessage.Number1 = 10; aRequestMessage.Number2 = 20; double aResult = aSender.sendRequestMessage(aRequestMessage, Double.class, MyRequestMessage.class); System.out.println(aRequestMessage.Number1 + " + " + aRequestMessage.Number2 + " = " + aResult);
// Request to calculate factorial. int aFactorial = aSender.sendRequestMessage((int)6, Integer.class, Integer.class); System.out.println("6! = " + aFactorial); } catch (Exception err) { EneterTrace.error("Calculating failed.", err); }
// Detach input channel and stop listening to responses. aSender.detachDuplexOutputChannel(); }
}


Constructor Summary
MultiTypedMessagesFactory()
          Constructs the factory with default XmlSerializer.
MultiTypedMessagesFactory(ISerializer serializer)
          Constructs the factory.
 
Method Summary
 IMultiTypedMessageReceiver createMultiTypedMessageReceiver()
          Creates multityped message receiver which can receive request messages and send response messages.
 IMultiTypedMessageSender createMultiTypedMessageSender()
          Creates multityped message sender which can send request messages and receive response messages.
 ISyncMultitypedMessageSender createSyncMultiTypedMessageSender()
          Creates mulityped message sender which sends a request message and then waits for the response.
 ISerializer getSerializer()
          Gets serializer for messages.
 GetSerializerCallback getSerializerProvider()
          Gets callback for retrieving serializer based on response receiver id.
 IThreadDispatcherProvider getSyncDuplexTypedSenderThreadMode()
          Gets the threading mode which is used for receiving connectionOpened and connectionClosed events in SyncDuplexTypedMessageSender.
 int getSyncResponseReceiveTimeout()
          Gets the timeout which is used for SyncMultitypedMessageSender.
 MultiTypedMessagesFactory setSerializer(ISerializer serializer)
          Sets serializer for messages.
 MultiTypedMessagesFactory setSerializerProvider(GetSerializerCallback serializerProvider)
          Sets callback for retrieving serializer based on response receiver id.
 MultiTypedMessagesFactory setSyncDuplexTypedSenderThreadMode(IThreadDispatcherProvider threadingMode)
          Sets the threading mode for receiving connectionOpened and connectionClosed events for SyncDuplexTypedMessageSender.
 MultiTypedMessagesFactory setSyncResponseReceiveTimeout(int milliseconds)
          Sets the timeout which is used for SyncMultitypedMessageSender.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

MultiTypedMessagesFactory

public MultiTypedMessagesFactory()
Constructs the factory with default XmlSerializer.


MultiTypedMessagesFactory

public MultiTypedMessagesFactory(ISerializer serializer)
Constructs the factory.

Parameters:
serializer - serializer which will serialize messages.
Method Detail

createMultiTypedMessageSender

public IMultiTypedMessageSender createMultiTypedMessageSender()
Description copied from interface: IMultiTypedMessagesFactory
Creates multityped message sender which can send request messages and receive response messages.

Specified by:
createMultiTypedMessageSender in interface IMultiTypedMessagesFactory
Returns:
multityped sender

createSyncMultiTypedMessageSender

public ISyncMultitypedMessageSender createSyncMultiTypedMessageSender()
Description copied from interface: IMultiTypedMessagesFactory
Creates mulityped message sender which sends a request message and then waits for the response.

Specified by:
createSyncMultiTypedMessageSender in interface IMultiTypedMessagesFactory
Returns:
synchronous multityped sender

createMultiTypedMessageReceiver

public IMultiTypedMessageReceiver createMultiTypedMessageReceiver()
Description copied from interface: IMultiTypedMessagesFactory
Creates multityped message receiver which can receive request messages and send response messages.

Specified by:
createMultiTypedMessageReceiver in interface IMultiTypedMessagesFactory
Returns:
multityped receiver

setSyncDuplexTypedSenderThreadMode

public MultiTypedMessagesFactory setSyncDuplexTypedSenderThreadMode(IThreadDispatcherProvider threadingMode)
Sets the threading mode for receiving connectionOpened and connectionClosed events for SyncDuplexTypedMessageSender. E.g. you use SyncDuplexTypedMessageSender and you want to route ConnectionOpened and ConnectionClosed events to the main UI thread of your application. Therefore you specify WindowsDispatching when you create your TCP duplex output channel which you then attach to the SyncDuplexTypedMessageSender.
Later when the application is running you call SyncDuplexTypedMessageSender.SendRequestMessage(..).
However if you call it from the main UI thread the deadlock occurs. Because this component is synchronous the SendRequestMessage(..) will stop the calling main UI thread and will wait for the response. But the problem is when the response comes the underlying TCP messaging will try to route it to the main UI thread (as was specified during creating TCP duplex output channel).
But because the main UI thread is suspending and waiting the message will never arrive.

Solution:
Do not specify the threading mode when you create yur duplex output channel but specify it using the SyncDuplexTypedSenderThreadMode property when you create SyncDuplexTypedMessageSender.

Parameters:
threadingMode - threading that shall be used for receiving connectionOpened and connectionClosed events.
Returns:
instance of this DuplexTypedMessagesFactory

getSyncDuplexTypedSenderThreadMode

public IThreadDispatcherProvider getSyncDuplexTypedSenderThreadMode()
Gets the threading mode which is used for receiving connectionOpened and connectionClosed events in SyncDuplexTypedMessageSender.

Returns:

setSerializer

public MultiTypedMessagesFactory setSerializer(ISerializer serializer)
Sets serializer for messages.

Parameters:
serializer - serializer
Returns:
this MultiTypedMessagesFactory

getSerializer

public ISerializer getSerializer()
Gets serializer for messages.

Returns:
serializer

getSerializerProvider

public GetSerializerCallback getSerializerProvider()
Gets callback for retrieving serializer based on response receiver id. This callback is used by MultiTypedMessageReceiver when it needs to serialize/deserialize the communication with MultiTypedMessageSender. Providing this callback allows to use a different serializer for each connected client. This can be used e.g. if the communication with each client needs to be encrypted using a different password.

The default value is null and it means SerializerProvider callback is not used and one serializer which specified in the Serializer property is used for all serialization/deserialization.
If SerializerProvider is not null then the setting in the Serializer property is ignored.

Returns:
GetSerializerCallback

setSerializerProvider

public MultiTypedMessagesFactory setSerializerProvider(GetSerializerCallback serializerProvider)
Sets callback for retrieving serializer based on response receiver id. This callback is used by MultiTypedMessageReceiver when it needs to serialize/deserialize the communication with MultiTypedMessageSender. Providing this callback allows to use a different serializer for each connected client. This can be used e.g. if the communication with each client needs to be encrypted using a different password.

The default value is null and it means SerializerProvider callback is not used and one serializer which specified in the Serializer property is used for all serialization/deserialization.
If SerializerProvider is not null then the setting in the Serializer property is ignored.

Parameters:
serializerProvider -
Returns:
GetSerializerCallback

setSyncResponseReceiveTimeout

public MultiTypedMessagesFactory setSyncResponseReceiveTimeout(int milliseconds)
Sets the timeout which is used for SyncMultitypedMessageSender. When SyncMultitypedMessageSender calls sendRequestMessage(..) then it waits until the response is received. This timeout specifies the maximum wating time. The default value is 0 and it means infinite time.

Parameters:
milliseconds - timeout in milliseconds
Returns:
this MultiTypedMessagesFactory

getSyncResponseReceiveTimeout

public int getSyncResponseReceiveTimeout()
Gets the timeout which is used for SyncMultitypedMessageSender. When SyncMultitypedMessageSender calls sendRequestMessage(..) then it waits until the response is received. This timeout specifies the maximum wating time. The default value is 0 and it means infinite time.

Returns:
timeout in milliseconds