Search This Blog

Friday, October 21, 2011

Eneter Messaging Framework 3.0

Summary: The third version of the messaging framework for the interprocess communication.


Eneter Messaging Framework is a lightweight framework for the interprocess communication based on messages.
Although the framework is lightweight (the assembly has about 300Kb), it provides quite comprehensive functionality allowing to implement advanced communication scenarios too.
(E.g. Service listening to HTTP and TCP at the same time, Communication across unstable network, Load Balancing, etc.)

The framework is free for non-comercial use (License) and runs in .NET 3.5, .NET 4.0, Windows Phone 7, Silverlight 3, Silverlight 4 and MONO 2.6.4.
Therefore, you can easily implement e.g. the communication between Windows Phone 7 and a standalone desktop application.
The framework can be downloaded from http://www.eneter.net.



Interprocess Communication
The communication between applications can be realized by various protocols or mechanisms. The right one depends on particular requirements. E.g. Are communicating applications on one machine? Are there any restrictions (e.g. Silverlight)?
The framework allows to implement the communication via:
  • Shared Memory - for the very fast communication between processes running on the same machine (faster than Named Pipes)
  •  Named Pipes - for the communication between processes running on the same machine
  •  TCP - for the communication between processes running on different machines.
  •  HTTP - for the communication between processes running on different machines.
  •  Silverlight Messaging - for the communication between Silverlight applications.

Encoding
Messages can be encoded with using:
  • XML Serializer - for simple serialization of messages into XML.
  • XML Data Contract Serializer - for the serialization of messages into XML using DataContract and DataMember attributes
  • Binary Serializer - for the fast serialization of messages into the binary format.
  • AES Serializer - for encrypting messages using Advanced Encryption Standard.
  • Rijndael Serializer - for encrypting messages using Rijndael encryption.
  • GZip Serializer - for compressing big messages before sending across the network.

The communication API is not bound to a particular protocol or encoding format, therefore your implementation stays same, does not matter what you use.

Routing Messages
The routing functionality provides components that can be placed on the communication path to control the sending behavior. E.g. forwarding messages to subscribed receivers, forwarding messages to a different address, load balancing, etc.
  • Broker - for sending notification messages to subscribed clients (i.e. publish-subscribe scenarios).
  • Router - for re-routing messages to a different address.
  • Dispatcher - for routing messages to multiple receivers (the same request processed by more services in parallel).
  • Load Balancer - for distributing workload across more computers (or processes, or threads).
  • Channel Wrapper/Unwrapper - for receiving various types of messages on one address (no need for long "if ... then" statements to recognize the type of received messages.)

Reliability
The communication across the network is typically less reliable as a local call performed inside the application. The network connection can be interrupted, or the receiving application can be temporarily unavailable. If your communication scenario requires to overcome these issues, the framework provides the following functionality:
  • Monitoring of the connection availability - for early detection of a disconnection.
  • Buffering of sent messages in case of a disconnection and automatic reconnect - for overcoming short disconnections e.g. caused by an unstable network.
  • Acknowledged messages - for confirmation if the message was delivered or not.

Security
The communication across the network is very easy to be observed and confidential data can be acquired by unauthorized persons. Therefore you may want to protect your data during the communication.
  • HTTPS, SSL and fast symetric encryption by using AES or Rijndael serializers.
If you are interested in more technical details about the framework, you can visit Eneter Online Info.

Enjoy the third version.

11 comments:

  1. good job, many thanks, it's really simple to create communication with eneter

    ReplyDelete
  2. one question, the behaviour of the monitored messaging system seems bit odd, it keeps signaling with the disconnect and connect events, no matter what ping frequency or timeout i had set,

    ReplyDelete
  3. I am glad you found the framework easy to use.
    The Monitored Messaging works like this:

    The duplex output channel sends the ping message and then waits for the response. If the response comes within 'pingResponseTimeout' then everything is ok and the duplex outputchannel waits 'pingFrequency' time before sending the next ping message.

    If the response does not come within the 'pingResponseTimeout' then the connection is considered broken and the duplex output channel should stop pinging.

    However, if you use Buffered Monitored Messaging, then the behavior is a bit different. In case the response for the ping does not arrive within the timeout, the connection is considered broken and Buffered Messaging (laying above Monitored Messaging) tries to reopen the connection - it repeatedly calls the underlying Monitored Messaging to open the connection.
    ==> I was thinking, that if you use Buffered Monitored Messaging, than maybe you observed attempts to reopen the connection.

    If this does not explain your question, please feel free to send me your code and I will investigate in detail what is happening.

    ReplyDelete
  4. Hi, thx for your reply,
    I did some test on the buffered monitored messaging, it come up with some strange results.
    I changed the sample code on the document(buffered monitored messaging, the calculator service), which display the some message whenever the event of ResponseReceiverConnected and ResponseReceiverDisconnected are risen,
    the results showed, at the beginning, the client connect to the server 3 times, this is unexpected, moreover, it disconnected and re-connected after ever few minutes, and it is unexpected,which i tested the code on a single local machine with the address 127.0.0.1, so the connection should never lost. this is all i know so far, thanks for your help

    ReplyDelete
  5. Hi Gaz,
    there is one more thing, I must say, I forgot to describe in the documentation:
    The BufferedMessaging (and also BufferedMonitoredMessaging) contains functionality allowing service automatically disconnect clients not using the service for a specified time. (I do not mean pinging from the client, but sending messages to use the service functionality.) If the client does not send a request message for the specified time, the service disconnects the client.
    So in our case of the calculator service, if the client does not invoke a request to calculate numbers, the calculator service disconnects this client after the specified time.
    The max inactive time for the client is specified via 'maxOfflineTime' on the service side. If you use the default constructor, the 'maxOfflineTime' is 10 seconds.

    In case of BufferedMonitoredMessaging (where buffered messaging is "merged" with monitored messaging), the behavior is a bit more tricky:
    The client is inactive (does not send requests) but is pinging to monitor the connection.
    But the pinging is not about using service, so the buffered messaging on service side actively disconnects this client after the specified time of inactivity. The disconnection is detected on the client side and because the client has also the buffered messaging, it tries to connect again. It connects and then the service disconnects it again after the specified inactivity time; the client connects again ... and so on.
    (If the client does not use a buffered messaging, it would not connect again. E.g. if it has only MonitoredMessaging.)

    I will definitely describe this feature in detail in the next release of the messaging framework.

    You can increase the maximum inactivity time for the client e.g. to 10 minutes like this:

    (the code on the service side)
    IMessagingSystemFactory aServiceMessagingSystem =
    new BufferedMonitoredMessagingFactory(
    anUnderlyingMessaging,
    new XmlStringSerializer(),
    TimeSpan.FromMinutes(5), // max client inactivity time
    TimeSpan.FromSeconds(1), // ping frequency
    TimeSpan.FromSeconds(2)); // response timeout

    I hope, my answer will help you.

    ReplyDelete
  6. Nice, Really fast and best communication with eneter.
    I have one question. i have one program which is in VC++ for windows CE with windows mobile 6 platform. i also want to use this eneter communication in this application. how can i do this?
    In this VC++, i have to include .h files and lib files how can i get these files. or is there any other way like API calls to the dll?

    ReplyDelete
    Replies
    1. I recommend you create a managed C++ library that will internally interact with Eneter but it will expose pure C++ code. (It will not expose any managed things.)
      E.g. you can create CommunicationWrapper.dll that will be implemented in managed C++. It will declare C++ interface without any managed stuff.

      E.g.:
      class IClient
      {
      public:
      virtual ~IClient(void){}

      virtual void OpenConnection() = 0;
      virtual void CloseConnection() = 0;
      virtual int SendCalculateRequest(int a, int b) = 0;
      };

      // And here are factories for creating and destructing.
      extern "C" WRAPPER_API IClient* CreateClient(const wchar_t* address);
      extern "C" WRAPPER_API void DestroyClient(IClient* client);

      Then you will create a class Client that will be derived from IClient. The class Client will not be visible outside the dll and its implementation will use Eneter. (since the library is managed whole Eneter functionality is available)

      Then in your native C++ application you will reference the wrapper library CommunicationWrapper.dll and the header file with IClient declaration. You can instantiate IClient by using factory methods and then just use it.

      Important: when you implement the native C++ library do not forget to copy Eneter.Messaging.Framework.dll (and other refernced .NET libraries if you have some) to the same directory as your executable. (directory where is executable and other dlls of your application.)

      Here is a short example I prepared:
      http://eneter.net/Downloads/Examples/CalculatorNative.zip

      Also here is some other useful link describing how to use managed .NET functionality in unmanaged C++:
      http://www.codeproject.com/Articles/10020/Using-managed-code-in-an-unmanaged-application

      I hope my response will help.

      Delete
    2. Hi,

      Sorry for delay,
      Help me in last segment error...

      This sample code and Information you given which help me lot. I implemented as per given sample. in VC++ i added communication wrapper dll and used. but while compiling it show me 2 errors

      1>LogIn.obj : error LNK2019: unresolved external symbol __imp_DestroyClient referenced in function __unwind$63393
      1>LogIn.obj : error LNK2019: unresolved external symbol __imp_CreateClient referenced in function __unwind$63393
      1>Windows Mobile 5.0 Smartphone SDK (ARMV4I)\Debug\BasicLoginWinCE.exe : fatal error LNK1120: 2 unresolved externals

      Commands Line shows as follows
      Creating temporary file "e:\LoginSample\Windows Mobile 5.0 Smartphone SDK (ARMV4I)\Debug\RSP00000139687200.rsp" with contents
      [
      /Od /I "e:\LoginSample\StelHost\Inc" /D "_DEBUG" /D "_WIN32_WCE=0x501" /D "UNDER_CE" /D "WIN32_PLATFORM_WFSP" /D "WINCE" /D "DEBUG" /D "ARM" /D "_ARM_" /D "SMARTPHONE2003_UI_MODEL" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /MTd /fp:fast /GR- /Yu"stdafx.h" /Fp"Windows Mobile 5.0 Smartphone SDK (ARMV4I)\Debug/BasicLoginWinCE.pch" /Fo"Windows Mobile 5.0 Smartphone SDK (ARMV4I)\Debug/" /Fd"Windows Mobile 5.0 Smartphone SDK (ARMV4I)\Debug/vc80.pdb" /W3 /c /Zi /TP

      .\LogIn.cpp

      ]
      Creating command line "cl.exe @"e:\LoginSample\Windows Mobile 5.0 Smartphone SDK (ARMV4I)\Debug\RSP00000139687200.rsp" /nologo"
      Creating temporary file "e:\LoginSample\Windows Mobile 5.0 Smartphone SDK (ARMV4I)\Debug\RSP00000239687200.rsp" with contents
      [
      /OUT:"Windows Mobile 5.0 Smartphone SDK (ARMV4I)\Debug\BasicLoginWinCE.exe" /INCREMENTAL /LIBPATH:".\StelHost\Lib" /MANIFEST:NO /NODEFAULTLIB:"oldnames.lib" /DEBUG /PDB:"e:\LoginSample\Windows Mobile 5.0 Smartphone SDK (ARMV4I)\Debug\BasicLoginWinCE.pdb" /SUBSYSTEM:WINDOWSCE /STACK:65536,4096 /ENTRY:"WinMainCRTStartup" /DYNAMICBASE:NO /subsystem:windowsce,5.02 WCE_StelHOST.lib ole32.lib oleaut32.lib uuid.lib

      ".\Windows Mobile 5.0 Smartphone SDK (ARMV4I)\Debug\LogIn.obj"

      ".\Windows Mobile 5.0 Smartphone SDK (ARMV4I)\Debug\SettngsDialog.obj"

      ".\Windows Mobile 5.0 Smartphone SDK (ARMV4I)\Debug\stdafx.obj"

      ".\Windows Mobile 5.0 Smartphone SDK (ARMV4I)\Debug\BasicLoginWinCE.res"
      ]
      Creating command line "link.exe @"e:\LoginSample\Windows Mobile 5.0 Smartphone SDK (ARMV4I)\Debug\RSP00000239687200.rsp" /NOLOGO /ERRORREPORT:PROMPT"

      Thanking you,

      Delete
    3. Hi Deepak,
      The 'unresolved external symbol' typically means the linker cannot find a library where a method is implemented. Or if a method is implemented in the library but not properly exported.
      I think you took declarations of methods from my example so I believe your problem will be the linker cannot find your wrapper library.
      Could you please check if you have correctly configured/setup path in your linker and if you have correctly setup the linker to use your 'wrapper.lib'?
      (The linker should know the path where is the '.lib' and also the name of the '.lib'.)
      Check how I set it in my example project.

      Delete
    4. Hi,

      My problem get solved... i remove extern "C" from CreateClient and DestroyClient in communicationapi.h and Instead of build dll i select lib both project get successfully build and run. (somewhere i read this to do) But i dont know whats link between this. if you know any details or any link where i can get info please share with me.

      But now code works properly.
      Thanks a lot lot. help me gr8.

      Delete
    5. Hi Deepak,
      It is good to hear the code is working for you. I do not know details about exporting C++ functionality from DLLs.
      But when I was preparing the example for you inspired from the following article. Maybe it helps:
      (see the section: C++ Mature Approach: Using an Abstract Interface)
      http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL

      Delete