Introduction

The one-way communication is a communication scenario where messages flow only in one direction - from sender to receiver.

The example bellow implements the client sending messages of specified type and the service receiving these messages and displaying them on the console.

The example is based on the Eneter Messaging Framework 2.0 that provides components for various communication scenarios.
(Full, not limited and for non-commercial usage free version of the framework can be downloaded from http://www.eneter.net. The online help for developers can be found at http://www.eneter.net/OnlineHelp/EneterMessagingFramework/Index.html.) 

1. Define Message Types 

You need to define message types you want to use for the communication. Also, because the serialization and deserialization (used during sending and receiving) can require some additional attributes in the declaration of the type, you also should consider what serialization will be used.

Binary Serialization

The data is serialized into array of bytes. The serialization is fast and consumes less memory as string serializations. It requires to use 'Serializable' attribute and the data must be declared in an assembly that is linked by the server and also by the client. (Here you can consider creating some assembly for shared data types.) The binary serialization is not supported by Silverlight. The serialization is based on BinaryFormater provided by .NET platform.

XML Serialization

The data is serialized into the string. The serialization is slower and consumes more memory as the binary serialization. It does not require, the server and the client link the same assembly with data types. The data can be declared separately on both sides. The XML serialization works in Silverlight too. The serialization is based on XmlSerializer provided by .NET platform.

Data Contract Serialization

The data is serialized as XML into the string. The serialization is based on DataContractSerializer provided by .NET platform. Therefore, you can use all data contract attributes to declare the data for the serialization / deserialization.

Our example uses the binary serialization, therefore here is the declaration for our message:

using System;

namespace CommonTypes
{
    [Serializable]
    public class Person
    {
        public string Name { get; set; }
        public int NumberOfItems { get; set; }
    }
}

2. Implement the Server

When you implement the interprocess communication, you must choose if you want to communicate via Named Pipes, TCP or HTTP protocol.

Named Pipes

// Create factory for messaging via Named Pipes.
IMessagingSystemFactory aMessagingSystemFactory = new NamedPipeMessagingSystemFactory();

// Create input channel for listening to messages.
IInputChannel anInputChannel = 
	aMessagingSystemFactory.CreateInputChannel("pipe.net://127.0.0.1/MyPipeName2");

TCP

// Create factory for messaging via TCP.
IMessagingSystemFactory aMessagingSystemFactory = new TcpMessagingSystemFactory();

// Create input channel for listening to messages.
IInputChannel anInputChannel = 
	aMessagingSystemFactory.CreateInputChannel("tcp://127.0.0.1:8091/");

HTTP

// Create factory for messaging via Http.
IMessagingSystemFactory aMessagingSystemFactory = new HttpMessagingSystemFactory();

// Create input channel for listening to messages.
IInputChannel anInputChannel = 
	aMessagingSystemFactory.CreateInputChannel("http://127.0.0.1:8091/MyService/");

Let's use Named Pipes in our example.

using System;
using CommonTypes;
using Eneter.Messaging.DataProcessing.Serializing;
using Eneter.Messaging.EndPoints.TypedMessages;
using Eneter.Messaging.MessagingSystems.MessagingSystemBase;
using Eneter.Messaging.MessagingSystems.NamedPipeMessagingSystem;

namespace TypedMessageServer
{
    class Program
    {
        // Strong type receiver for the type Person.
        static private ITypedMessageReceiver<Person> myReceiver;

        static void Main(string[] args)
        {
            // Create receiver for the message type 'Person' with binary serializer.
            ISerializer aSerializer = new BinarySerializer();
            ITypedMessagesFactory aTypedMessagesFactory = new TypedMessagesFactory(aSerializer);
            myReceiver = aTypedMessagesFactory.CreateTypedMessageReceiver<Person>();
            myReceiver.MessageReceived += OnMessageReceived;

            // Create input channel listening to Named Pipe.
            // Note: This is a one-way channel. Therefore, it can just receive messages.
            // Note: Do not use '/' at the end of the address.
            IMessagingSystemFactory aMessaging = new NamedPipeMessagingSystemFactory();
            IInputChannel anInputChannel = aMessaging.CreateInputChannel("//127.0.0.1/MyPipeName2");

            // Attach input channel ans start listening.
            myReceiver.AttachInputChannel(anInputChannel);

            Console.WriteLine("The service is listening. Press enter to stop.\n");
            Console.ReadLine();

            myReceiver.DetachInputChannel();
        }

        static void OnMessageReceived(object sender, TypedMessageReceivedEventArgs<Person> e)
        {
            // If there was a problem with the receiving.
            if (e.ReceivingError != null)
            {
                Console.WriteLine("Detected problem during receiving: " + e.ReceivingError.Message);
            }
            else
            {
                Console.WriteLine("Received Message:");
                Console.WriteLine("Name: " + e.MessageData.Name);
                Console.WriteLine("Number of items: " + e.MessageData.NumberOfItems.ToString());
                Console.WriteLine();
            }
        }
    }
}

3. Implement the Client

And here is the implementation for the client sending messages of type Person:

using System;
using System.Windows.Forms;
using CommonTypes;
using Eneter.Messaging.DataProcessing.Serializing;
using Eneter.Messaging.EndPoints.TypedMessages;
using Eneter.Messaging.MessagingSystems.MessagingSystemBase;
using Eneter.Messaging.MessagingSystems.NamedPipeMessagingSystem;

namespace TypedMessageClient
{
    public partial class Form1 : Form
    {
        private ITypedMessageSender<Person> myMessageSender;

        public Form1()
        {
            InitializeComponent();

            // Create input channel listening to Named Pipe.
            // Note: This is a one-way channel. Therefore, it can just receive messages.
            IMessagingSystemFactory aMessaging = new NamedPipeMessagingSystemFactory();
            IOutputChannel anOutputChannel = aMessaging.CreateOutputChannel("//127.0.0.1/MyPipeName2");

            // Create the message sender sending the class of type 'Person'.
            // The sender will use the binary serializer.
            ISerializer aSerializer = new BinarySerializer();
            ITypedMessagesFactory aTypedMessagesFactory = new TypedMessagesFactory(aSerializer);
            myMessageSender = aTypedMessagesFactory.CreateTypedMessageSender<Person>();

            // Attach the output channel and be able to send messages.
            myMessageSender.AttachOutputChannel(anOutputChannel);
        }

        private void SendButton_Click(object sender, EventArgs e)
        {
            // Prepare the message.
            Person aPerson = new Person();
            aPerson.Name = NameTextBox.Text;
            aPerson.NumberOfItems = int.Parse(NumberOfItemsTextBox.Text);

            // Send the message.
            myMessageSender.SendMessage(aPerson);
        }
    }
}

And here are communicating applications:


推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"