我有一个Windows服务和一个graphics用户界面需要相互沟通。 可以随时发送消息。
我正在看使用NamedPipes,但似乎你不能同时读取和写入stream(或者至less我找不到任何涵盖这种情况的例子)。
是否有可能通过单个NamedPipe进行这种双向通信? 或者我需要打开两个pipe道(一个来自GUI->服务,另一个来自服务 – > GUI)?
使用WCF你可以使用双工命名管道
// 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(); }
实施服务
[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(); } }
主持服务
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(); } } }
创建客户端应用程序,在这个例子中,Client类实现了回叫合同。
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"); } }
使用单个点累积消息(在这种情况下,单个管道)也会强制您自己处理消息的方向(除此之外,还必须使用系统范围的管道锁)。
所以使用两个方向相反的管道。
(另一种选择是使用2个MSMQ队列)。
您命名的管道流类(服务器或客户端)必须使用InDut的PipeDirection构造。 您需要一个NamedPipeserverStream,可能在您的服务中,可以由任意数量的NamedPipeClientStream对象共享。 使用管道的名称和方向构建NamedPipeserverStream,使用管道的名称,服务器的名称和PipeDirection构建NamedPipeClientStream,您应该很好。