使用 WCF 和 NetNamedPipeBinding 进行 IPC

Posted

技术标签:

【中文标题】使用 WCF 和 NetNamedPipeBinding 进行 IPC【英文标题】:Using WCF and NetNamedPipeBinding for IPC 【发布时间】:2010-10-08 19:00:44 【问题描述】:

我正在尝试学习 WCF 以将其用作主机/插件系统的 IPC 机制。主机需要能够调用插件来启动/停止它,插件需要回调服务器来执行日志记录。

我做了一个简单的测试用例,主机使用以下 ServiceContract 在net.pipe://localhost/SampleServer 创建端点:

[ServiceContract]
public interface IWcfServer

    [OperationContract]
    void Log(string message);

插件使用以下 ServiceContract 在net.pipe://localhost/SampleClient 上创建一个端点:

[ServiceContract]
public interface IWcfClient

    [OperationContract]
    string Init();

这是我如何设置每个端点的示例:

this.server = new ServiceHost(this);
this.server.AddServiceEndpoint(typeof(IWcfServer), 
                               new NetNamedPipeBinding(), 
                               "net.pipe://localhost/SampleServer");
this.server.Open();

以下是我如何拨打电话的示例:

ChannelFactory<IWcfClient> factory = new ChannelFactory<IWcfClient>(
                            new NetNamedPipeBinding(),
                            new EndpointAddress("net.pipe://localhost/SampleClient"));
IWcfClient client = factory.CreateChannel();
using ((IClientChannel)client)

    client.Init());

我已经确认主机可以调用plugin.Init(),插件可以调用host.Log(message)没有问题。但是,如果发生以下情况:

    主机调用plugin.Init() plugin.Init()执行期间,插件尝试调用host.Log(message)

应用程序冻结,1 分钟后我收到TimeoutException。有人对我做错了什么有任何想法吗?

【问题讨论】:

仅供参考,void 上的“IsOneWay”-返回Log() 可能有助于避免阻塞[OperationContract(IsOneWay = true)] - 请参阅msdn.microsoft.com/en-us/library/…,如dotnet-experience.blogspot.com/2012/02/… 中所述 【参考方案1】:

服务主机的 InstanceContextMode 是什么?如果是单例,它将阻塞直到 Init() 返回 - 导致循环依赖。

【讨论】:

是的。我发现对于那个特定的示例,如果我添加 UseSynchronizationContext=false,它会起作用,但对于真正的应用程序,我最终重写了一些东西以使用 InstanceContextMode.PerCall。【参考方案2】:

1 分钟是标准的 wcf 超时时间。

你有循环引用吗?

另外,当你调用正在监听的 client.init 时,为什么你有 2 个合约?

【讨论】:

没有循环引用,请参阅我对 Sajay 消息的评论。我有两个合约和两个不同的端点,因为主机和插件之间有两条独立的通信路径。主机实现 IWcfServer 并调用 plugin.Init,而插件实现 IWcfClient 并调用 host.Log。【参考方案3】:

为 WCF 打开 E2E 跟踪以检查究竟是什么超时。 -http://msdn.microsoft.com/en-us/library/ms733025.aspx。此外,您的方法可能会导致死锁,因为 init 可能需要 log 并且 log 可能需要 init 首先发生或类似的事情。

【讨论】:

我知道没有循环引用,因为当前日志“实现”只是 MessageBox.Show(message)。我将启用该跟踪并在明天查看它。【参考方案4】:

"net.pipe://localhost/SampleServer" “net.pipe://localhost/SampleClient” 服务器和客户端有两个不同的 URL。这是个问题!

【讨论】:

不是,不是。它使用两个不同的管道进行双向通信,一个用于服务器 -> 客户端,另一个用于客户端 -> 服务器。因此有不同的端点。

以上是关于使用 WCF 和 NetNamedPipeBinding 进行 IPC的主要内容,如果未能解决你的问题,请参考以下文章

如何使用故障契约和 jquery ajax 处理 wcf 错误

使用wcf.js和node.js与Alexa联系WCF服务无法正常工作?

iOS和使用Json进行请求/响应的消费WCF服务方法

WCF、EF 和 UWP

使用 Windows 身份验证的 IIS 托管 WCF 服务和 SQL 查询

WCF 和 IIS 的实体框架问题