Asynchronous two-way communication with Windows Named Pipes (.Net)

I have a windows service and a GUI that need to communicate with each other. You can also send messages at any time.

I am considering using NamedPipes, but it seems that you cannot read and write to the stream at the same time (or at least I cannot find examples that cover this case).

Is it possible to make this two-way communication through a single NamedPipe? Or do I need to open two pipes (one from the GUI-> service and one from the service โ†’ GUI)?

+14
source share
3 answers

With WCF, you can use duplex named pipes

// Create a contract that can be used as a callback public interface IMyCallbackService { [OperationContract(IsOneWay = true)] void NotifyClient(); } // Define your service contract and specify the callback contract [ServiceContract(CallbackContract = typeof(IMyCallbackService))] public interface ISimpleService { [OperationContract] string ProcessData(); } 

Implement service

 [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)] public class SimpleService : ISimpleService { public string ProcessData() { // Get a handle to the call back channel var callback = OperationContext.Current.GetCallbackChannel<IMyCallbackService>(); callback.NotifyClient(); return DateTime.Now.ToString(); } } 

Enable service

 class Server { static void Main(string[] args) { // Create a service host with an named pipe endpoint using (var host = new ServiceHost(typeof(SimpleService), new Uri("net.pipe://localhost"))) { host.AddServiceEndpoint(typeof(ISimpleService), new NetNamedPipeBinding(), "SimpleService"); host.Open(); Console.WriteLine("Simple Service Running..."); Console.ReadLine(); host.Close(); } } } 

Create a client application, in this example the Client class executes a callback contract.

 class Client : IMyCallbackService { static void Main(string[] args) { new Client().Run(); } public void Run() { // Consume the service var factory = new DuplexChannelFactory<ISimpleService>(new InstanceContext(this), new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/SimpleService")); var proxy = factory.CreateChannel(); Console.WriteLine(proxy.ProcessData()); } public void NotifyClient() { Console.WriteLine("Notification from Server"); } } 
+25
source

Using one point to accumulate messages (in this case, one channel) forces you to process the direction of the message yourself (in addition to this, you must use the system lock for the channel).

So, use 2 pipes with opposite directions.

(Another option is to use two MSMQ queues).

+2
source

Your named stream flows (server or client) must be constructed using the PipeDirection of InOut. You need one NamedPipeServerStream, possibly in your service, which can be shared by any number of NamedPipeClientStream objects. Build a NamedPipeServerStream with the channel name and direction, and NamedPipeClientStream with the channel name, server name and PipeDirection, and you should be good to go.

+1
source

All Articles