我有一个需要相互通信的 Windows 服务和一个 GUI。两者都可以随时发送消息。
我正在考虑使用 NamedPipes,但您似乎无法同时读取和写入流(或者至少我找不到任何涵盖这种情况的示例)。
是否可以通过单个 NamedPipe 进行这种双向通信?还是我需要打开两个管道(一个来自 GUI->service,一个来自 service->GUI)?
我有一个需要相互通信的 Windows 服务和一个 GUI。两者都可以随时发送消息。
我正在考虑使用 NamedPipes,但您似乎无法同时读取和写入流(或者至少我找不到任何涵盖这种情况的示例)。
是否可以通过单个 NamedPipe 进行这种双向通信?还是我需要打开两个管道(一个来自 GUI->service,一个来自 service->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();
}
}
}
创建客户端应用程序,在此示例中,客户端类实现回调合同。
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");
}
}
您的命名管道流类(服务器或客户端)必须使用PipeDirection
of构建InOut
。您需要一个NamedPipeServerStream
,可能在您的服务中,可以由任意数量的NamedPipeClientStream
对象共享。NamedPipeServerStream
使用管道名称和方向构造 ,使用NamedPipeClientStream
管道名称、服务器名称和 构造PipeDirection
,你应该可以开始了。
使用单点来累积消息(在这种情况下为单个管道)会迫使您自己处理消息的方向(此外,您必须对管道使用系统范围的锁定)。
所以使用2个方向相反的管道。
(另一种选择是使用 2 个 MSMQ 队列)。