eneter.messaging.endpoints.typedmessages
Class DuplexTypedMessagesFactory

java.lang.Object
  extended by eneter.messaging.endpoints.typedmessages.DuplexTypedMessagesFactory
All Implemented Interfaces:
IDuplexTypedMessagesFactory

public class DuplexTypedMessagesFactory
extends java.lang.Object
implements IDuplexTypedMessagesFactory

Factory to create typed message senders and receivers.
The following example shows how to send and receive messages:

Implementation of receiver (service):

 class MyReceiver
 {
      // Typed message receiver receiving 'Item' and responding 'String'.
      private IDuplexTypedMessageReceiver<String, Item> myReceiver;

      public void startListening() throws Exception
      {
          // Create message receiver receiving 'Item' and responding 'String'.
          // Note: XmlStringSerializer is used by default.
          IDuplexTypedMessagesFactory aReceiverFactory = new DuplexTypedMessagesFactory();
          myReceiver = aReceiverFactory.createDuplexTypedMessageReceiver(String.class, Item.class);

          // Subscribe to receive messages.
          myReceiver.messageReceived().subscribe(myOnMessageHandler);

          // Create TCP messaging.
          IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
          IDuplexInputChannel anInputChannel = aMessaging.createDuplexInputChannel("tcp://127.0.0.1:8033/");

          // Attach input channel and start listening to messages.
          myReceiver.attachDuplexInputChannel(anInputChannel);
      }

      public void stopListening()
      {
          // Detach input channel and stop listening.
          myReceiver.detachDuplexInputChannel();
      }


      private void onMessageReceived(Object sender, TypedRequestReceivedEventArgs<Item> e)
          throws Exception
      {
          // Get the response message.
          Item anItem = e.getMessage();
          ...
          // Send back a response message.
          // Note: The response is declared as String.
          String aResponseMsg = "Response message.";
          myReceiver.sendResponseMessage(e.getResponseReceiverId(), aResponseMsg);
      }


      // Received message handler
      EventHandler<TypedRequestReceivedEventArgs<Item>> myOnResponseHandler = new EventHandler<TypedRequestReceivedEventArgs<Item>>()
      {
          public void invoke(Object x, TypedRequestReceivedEventArgs<Item> y)
              throws Exception
          {
              onMessageReceived(x, y);
          }
      }
 }
 
 

Implementation of sender (client):
 // Message to be sent and received.
 public class Item
 {
      public String name;
      public int amount;
 }

 class MySender
 {
      // Typed message sender sending 'Item' and as a response receiving 'String'.
      private IDuplexTypedMessageSender<String, Item> mySender;

      public void openConnection() throws Exception
      {
          // Create message sender sending 'Item' and receiving 'String'.
          // Note: XmlStringSerializer is used by default.
          IDuplexTypedMessagesFactory aSenderFactory = new DuplexTypedMessagesFactory();
          mySender = aSenderFactory.createDuplexTypedMessageSender(String.class, Item.class);
          
          // Subscribe to receive response messages.
          mySender.responseReceived().subscribe(myOnResponseHandler);

          // Create TCP messaging.
          IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
          IDuplexOutputChannel anOutputChannel = aMessaging.createDuplexOutputChannel("tcp://127.0.0.1:8033/");

          // Attach output channel and be able to send messages and receive responses.
          mySender.attachDuplexOutputChannel(anOutputChannel);
      }

      public void closeConnection()
      {
          // Detach output channel and stop listening to response messages.
          mySender.detachDuplexOutputChannel();
      }

      public void sendMessage(Item message) throws Exception
      {
          mySender.sendMessage(message);
      }

      private void onResponseReceived(Object sender, TypedResponseReceivedEventArgs<String> e)
      {
          // Get the response message.
          String aReceivedResponse = e.getResponseMessage();
          ...
      }


      // Response message handler
      EventHandler<TypedResponseReceivedEventArgs<String>> myOnResponseHandler = new EventHandler<TypedResponseReceivedEventArgs<String>>()
      {
          public void invoke(Object x, TypedRequestReceivedEventArgs<String> y)
              throws Exception
          {
              onResponseReceived(x, y);
          }
      }
 }
 
 
In case you need a synchronous communication where client needs to wait for the response you can use synchronous sender:
 // Message to be sent and received.
 public class Item
 {
      public String name;
      public int amount;
 }

 class MySender
 {
      // Typed message sender sending 'Item' and as a response receiving 'String'.
      private ISyncDuplexTypedMessageSender<String, Item> mySender;

      public void openConnection() throws Exception
      {
          // Create message sender sending 'Item' and receiving 'String'.
          // Note: XmlStringSerializer is used by default.
          IDuplexTypedMessagesFactory aSenderFactory = new DuplexTypedMessagesFactory();
          mySender = aSenderFactory.createSyncDuplexTypedMessageSender(String.class, Item.class);

          // Create TCP messaging.
          IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
          IDuplexOutputChannel anOutputChannel = aMessaging.createDuplexOutputChannel("tcp://127.0.0.1:8033/");

          // Attach output channel and be able to send messages and receive responses.
          mySender.attachDuplexOutputChannel(anOutputChannel);
      }

      public void closeConnection()
      {
          // Detach output channel and stop listening to response messages.
          mySender.detachDuplexOutputChannel();
      }

      // Sends message and waits for the response.
      public String sendMessage(Item message) throws Exception
      {
          String aResponse = mySender.sendMessage(message);
          return aResponse;
      }
 }
 
 


Constructor Summary
DuplexTypedMessagesFactory()
          Constructs the factory with XmlStringSerializer.
DuplexTypedMessagesFactory(ISerializer serializer)
          Constructs the factory with specified serializer.
 
Method Summary
<TResponse,TRequest>
IDuplexTypedMessageReceiver<TResponse,TRequest>
createDuplexTypedMessageReceiver(java.lang.Class<TResponse> responseMessageClazz, java.lang.Class<TRequest> requestMessageClazz)
          Creates message receiver (service) which can receive messages and send back response messages.
<TResponse,TRequest>
IDuplexTypedMessageSender<TResponse,TRequest>
createDuplexTypedMessageSender(java.lang.Class<TResponse> responseMessageClazz, java.lang.Class<TRequest> requestMessageClazz)
          Creates message sender (client) which can send messages and receive response messages.
<TResponse,TRequest>
ISyncDuplexTypedMessageSender<TResponse,TRequest>
createSyncDuplexTypedMessageSender(java.lang.Class<TResponse> responseMessageClazz, java.lang.Class<TRequest> requestMessageClazz)
          Creates message sender (client) 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 SyncDuplexTypedMessageSender.
 DuplexTypedMessagesFactory setSerializer(ISerializer serializer)
          Sets serializer for messages.
 DuplexTypedMessagesFactory setSerializerProvider(GetSerializerCallback serializerProvider)
          Sets callback for retrieving serializer based on response receiver id.
 DuplexTypedMessagesFactory setSyncDuplexTypedSenderThreadMode(IThreadDispatcherProvider threadingMode)
          Sets the threading mode for receiving connectionOpened and connectionClosed events for SyncDuplexTypedMessageSender.
 DuplexTypedMessagesFactory setSyncResponseReceiveTimeout(int milliseconds)
          Sets the timeout which is used for SyncDuplexTypedMessageSender.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

DuplexTypedMessagesFactory

public DuplexTypedMessagesFactory()
Constructs the factory with XmlStringSerializer. The factory will create senders and receivers with the default XmlStringSerializer.


DuplexTypedMessagesFactory

public DuplexTypedMessagesFactory(ISerializer serializer)
Constructs the factory with specified serializer. The factory will create senders and receivers with the specified serializer which will be used to serialize/deserialize messages.
For possible serializers you can refer to eneter.messaging.dataprocessing.serializing

Parameters:
serializer - serializer that will be used to serialize/deserialize messages.
Method Detail

createDuplexTypedMessageSender

public <TResponse,TRequest> IDuplexTypedMessageSender<TResponse,TRequest> createDuplexTypedMessageSender(java.lang.Class<TResponse> responseMessageClazz,
                                                                                                         java.lang.Class<TRequest> requestMessageClazz)
Description copied from interface: IDuplexTypedMessagesFactory
Creates message sender (client) which can send messages and receive response messages.

Specified by:
createDuplexTypedMessageSender in interface IDuplexTypedMessagesFactory
Parameters:
responseMessageClazz - type of response messages
requestMessageClazz - type of request messages
Returns:
message sender

createSyncDuplexTypedMessageSender

public <TResponse,TRequest> ISyncDuplexTypedMessageSender<TResponse,TRequest> createSyncDuplexTypedMessageSender(java.lang.Class<TResponse> responseMessageClazz,
                                                                                                                 java.lang.Class<TRequest> requestMessageClazz)
Description copied from interface: IDuplexTypedMessagesFactory
Creates message sender (client) which sends a request message and then waits for the response.

Specified by:
createSyncDuplexTypedMessageSender in interface IDuplexTypedMessagesFactory
Parameters:
responseMessageClazz - type of response messages
requestMessageClazz - type of request messages
Returns:
synchronous message sender

createDuplexTypedMessageReceiver

public <TResponse,TRequest> IDuplexTypedMessageReceiver<TResponse,TRequest> createDuplexTypedMessageReceiver(java.lang.Class<TResponse> responseMessageClazz,
                                                                                                             java.lang.Class<TRequest> requestMessageClazz)
Description copied from interface: IDuplexTypedMessagesFactory
Creates message receiver (service) which can receive messages and send back response messages.

Specified by:
createDuplexTypedMessageReceiver in interface IDuplexTypedMessagesFactory
Parameters:
responseMessageClazz - type of response messages
requestMessageClazz - type of request messages
Returns:
duplex typed message receiver

setSyncDuplexTypedSenderThreadMode

public DuplexTypedMessagesFactory 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 WPF based 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 DuplexTypedMessagesFactory setSerializer(ISerializer serializer)
Sets serializer for messages.

Parameters:
serializer - serializer
Returns:
this DuplexTypedMessagesFactory

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 DuplexTypedMessageReceiver when it needs to serialize/deserialize the communication with DuplexTypedMessageSender. 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 DuplexTypedMessagesFactory setSerializerProvider(GetSerializerCallback serializerProvider)
Sets callback for retrieving serializer based on response receiver id. This callback is used by DuplexTypedMessageReceiver when it needs to serialize/deserialize the communication with DuplexTypedMessageSender. 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 DuplexTypedMessagesFactory setSyncResponseReceiveTimeout(int milliseconds)
Sets the timeout which is used for SyncDuplexTypedMessageSender. When SyncDuplexTypedMessageSender 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 DuplexTypedMessagesFactory

getSyncResponseReceiveTimeout

public int getSyncResponseReceiveTimeout()
Gets the timeout which is used for SyncDuplexTypedMessageSender. When SyncDuplexTypedMessageSender 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