Search This Blog

Sunday, January 29, 2012

SImple Request-Response Communication using TCP

Summary: Very simple example showing how to implement request-response communication using TCP.



Introduction
The example bellow implements a request-response communication scenario using TCP. The client application sends a simple text message to the service. When the service receives the text message, it responses back to the client with the text message too.
The whole implementation is very simple and requires  only few lines of code.


The example can be downloaded from  http://eneter.net/Downloads/Examples/SimpleTcp.zip.
To run the example, first execute the service application and then the client application. You can run multiple client applications.

The example bellow uses Eneter Messaging Framework that provides functionality for various communication scenarios.
(The framework is free for non-commercial use (License) and can be downloaded from http://www.eneter.net.
More detailed technical info can be found at http://www.eneter.net/OnlineHelp/EneterMessagingFramework/Index.html.)



Client Application
The client is a simple application containg a button to send a text message. When it receives the response message, it displayes it in the text box.

The implementation is very simple.

using System;
using System.Windows.Forms;
using Eneter.Messaging.EndPoints.TypedMessages;
using Eneter.Messaging.MessagingSystems.MessagingSystemBase;
using Eneter.Messaging.MessagingSystems.TcpMessagingSystem;

namespace HelloWorldTcpClient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            OpenConnection();
        }

        private void OpenConnection()
        {
            // Create message sender.
            // It sends string and as a response receives also string.
            IDuplexTypedMessagesFactory aTypedMessagesFactory = new DuplexTypedMessagesFactory();
            myMessageSender = aTypedMessagesFactory.CreateDuplexTypedMessageSender<string, string>();

            // Subscribe to receive response messages.
            myMessageSender.ResponseReceived += OnResponseReceived;

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

            // Attach the output channel to the message sender and be able
            // send messages and receive responses.
            myMessageSender.AttachDuplexOutputChannel(anOutputChannel);
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            // Detach output channel and stop listening to response messages.
            myMessageSender.DetachDuplexOutputChannel();
        }

        private void SendMessageBtn_Click(object sender, EventArgs e)
        {
            // Send message.
            myMessageSender.SendRequestMessage(MessageTextBox.Text);
        }

        private void OnResponseReceived(object sender, TypedResponseReceivedEventArgs<string> e)
        {
            // Display received response.
            // Note: This response does not come in the UI thread.
            //       Therefore, we ninvoke it in the UI thread.
            InvokeInUIThread(() => ReceivedResponseTextBox.Text = e.ResponseMessage);
        }

        // Helper method to invoke some functionality in UI thread.
        private void InvokeInUIThread(Action uiMethod)
        {
            // If we are not in the UI thread then we must synchronize via the invoke mechanism.
            if (InvokeRequired)
            {
                Invoke(uiMethod);
            }
            else
            {
                uiMethod();
            }
        }

        private IDuplexTypedMessageSender<string, string> myMessageSender;
    }
}

Service Application
The service is a simple console application listening via TCP to messages. When it receives a message, it sends back the text message.

Here is the whole service implementation:

using System;
using Eneter.Messaging.EndPoints.TypedMessages;
using Eneter.Messaging.MessagingSystems.MessagingSystemBase;
using Eneter.Messaging.MessagingSystems.TcpMessagingSystem;

namespace HelloWorldTcpService
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create message receiver.
            // It receives string and responses also string.
            IDuplexTypedMessagesFactory aTypedMessagesFactory = new DuplexTypedMessagesFactory();
            IDuplexTypedMessageReceiver<string, string> aMessageReceiver
                = aTypedMessagesFactory.CreateDuplexTypedMessageReceiver<string, string>();

            // Subscribe to receive messages.
            aMessageReceiver.MessageReceived += OnMessageReceived;

            // Create input channel that will listen messages via TCP.
            IMessagingSystemFactory aTcpMessaging = new TcpMessagingSystemFactory();
            IDuplexInputChannel anInputChannel = aTcpMessaging.CreateDuplexInputChannel("tcp://127.0.0.1:8055/");

            // Attach the input channel to the message receiver and start listening.
            aMessageReceiver.AttachDuplexInputChannel(anInputChannel);

            Console.WriteLine("TCP service is running. To stop press ENTER.");
            Console.ReadLine();

            // Detach the input channel and stop listening.
            aMessageReceiver.DetachDuplexInputChannel();
        }

        private static void OnMessageReceived(object sender, TypedRequestReceivedEventArgs<string> e)
        {
            // Display receive message.
            Console.WriteLine("Received message: " + e.RequestMessage);

            // Send back simple response.
            string aResponseMessage = "Thanks for " + e.RequestMessage;
            IDuplexTypedMessageReceiver<string, string> aReceiver
                = (IDuplexTypedMessageReceiver<string, string>)sender;
            aReceiver.SendResponseMessage(e.ResponseReceiverId, aResponseMessage);
        }
    }
}

And here are communicating applications.

No comments:

Post a Comment