【问题标题】:Async two-way communication with Windows Named Pipes (.Net)与 Windows 命名管道 (.Net) 的异步双向通信
【发布时间】:2013-05-02 05:15:54
【问题描述】:

我有一个需要相互通信的 Windows 服务和一个 GUI。两者都可以随时发送消息。

我正在考虑使用 NamedPipes,但您似乎无法同时读取和写入流(或者至少我找不到任何涵盖这种情况的示例)。

是否可以通过单个 NamedPipe 进行这种双向通信? 还是我需要打开两个管道(一个来自 GUI->service,一个来自 service->GUI)?

【问题讨论】:

  • 您可以使用 WCF Duplex NamedPipes,我使用这种方法进行服务/应用程序通信,这里有一个很好的示例可能会有所帮助。tech.pro/tutorial/855/…

标签: c# .net windows asynchronous named-pipes


【解决方案1】:

使用 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");
    }
}

【讨论】:

  • 感谢您的详细回复。我已经使用了这种方法,因为它似乎比使用 2 个命名管道更简单。
  • 任何我可以让 Windows 服务正常运行但在尝试添加服务引用时找不到服务的想法我得到“net.pipe://localhost/service1”。从管道读取错误:管道已结束。 (109, 0x6d)。
【解决方案2】:

使用单点来累积消息(在这种情况下是单个管道)会迫使您自己处理消息的方向(此外,您还必须为管道使用系统范围的锁定)。

所以使用两个方向相反的管道。

(另一种选择是使用 2 个 MSMQ 队列)。

【讨论】:

    【解决方案3】:

    您的命名管道流类(服务器或客户端)必须使用 InOut 的 PipeDirection 构造。您需要一个 NamedPipeServerStream,可能在您的服务中,它可以由任意数量的 NamedPipeClientStream 对象共享。构造带有管道名称和方向的 NamedPipeServerStream,以及带有管道名称、服务器名称和 PipeDirection 的 NamedPipeClientStream,你应该可以开始了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-07
      • 1970-01-01
      • 1970-01-01
      • 2018-08-03
      • 1970-01-01
      相关资源
      最近更新 更多