10

我是 WCF 服务的开发人员。我的测试客户可以很好地使用它。但是当涉及到真正的客户端(使用相同的客户端代理)时,它会失败。相同的 WCF 服务适用于 netTcpBinding,此错误仅发生在 netNamedPipeBinding 中,即使 ConcurrencyMode = ConcurrencyMode.Single

这是例外

在 net.pipe://localhost/MyService 上没有可以接受消息的端点侦听。这通常是由不正确的地址或 SOAP 操作引起的。有关更多详细信息,请参阅 InnerException(如果存在)。

服务器堆栈跟踪:在

System.ServiceModel.Channels.PipeConnectionInitiator.GetPipeName(Uri uri) at System.ServiceModel.Channels.NamedPipeConnectionPoolRegistry.NamedPipeConnectionPool.GetPoolKey(EndpointAddress address, Uri via) at System.ServiceModel.Channels.CommunicationPool`2.TakeConnection(EndpointAddress address, Uri via , TimeSpan timeout, TKey& key) at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout) at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout) 在 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) 在 System.ServiceModel.Channels.ServiceChannel。CallOnceManager.CallOnce(TimeSpan 超时,CallOnceManager 级联)
在 System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout) 在 System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) 在系统。 System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage 消息) 处的 ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)

在 [0] 处重新抛出异常:在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) 处的 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)

内部异常

PipeException:“在您的本地计算机上找不到管道端点 'net.pipe://localhost/MyService'。”

4

3 回答 3

22

堆栈跟踪显示客户端 WCF 通道堆栈在尝试从服务 URL 派生服务使用的命名管道的实际名称时失败。该服务通过将一个小结构放置在包含 GUID 作为其字段之一的命名共享内存部分中来发布管道名称(这是一个每次服务重新启动时都会更改的 GUID) 。用于共享内存部分的名称是通过应用一种算法从服务 URL 派生的,该算法编译到 NetNamedPipeBinding 的服务器端和客户端 WCF 代码中。

问题中报告的异常实际上意味着将算法应用于服务 URL 以提供名称后,客户端代码无法打开该名称的共享内存部分的句柄。正如异常消息所述,这可能意味着没有服务在侦听用于派生名称的服务 URL。但它可能意味着内存部分在那里,服务也在那里,但是客户端代码没有在允许它访问共享内存的安全上下文中运行。

在 Vista 之前的 Windows 平台上,WCF 客户端不太可能缺少打开共享内存、从中读取管道名称 GUID 并成功连接到服务管道的安全权限。但是在 Vista 和更高版本的平台上,有新的安全机制使得这成为更常见的故障场景。

Vista 为命名内核对象引入了不同命名空间的概念:每个登录会话都有一个全局(机器范围)命名空间和一个私有命名空间。NetNamedPipeBinding 客户端代码将在查找通告管道名称的共享内存部分时尝试这两个名称空间。如果服务器使用全局名称创建了共享内存,或者如果服务和客户端在同一个登录会话中运行,那么客户端将找到它要查找的内容。但是,如果服务无法在全局命名空间中创建对象(它总是首先尝试这样做),那么它将回退到创建私有会话命名空间,然后只有在同一会话中运行的客户端才能看到它。在 Vista 和更高版本的平台中创建全局命名空间内核对象需要特殊权限,通常只有以“管理员身份”运行的 Windows 服务进程和应用程序才会拥有。一个常见的陷阱是尝试在 Windows 服务中创建客户端,并尝试连接到在交互式用户会话中运行的应用程序中托管的 WCF NetNamedPipe 服务。

如果客户端代码在比托管服务的代码更低的完整性上下文(例如浏览器插件)中运行,Vista 强制完整性机制还可以防止假定的客户端连接到 WCF NetNamedPipeBinding 服务。

我想问题中报告的症状,测试客户端工作但真实客户端不工作,几乎可以肯定是由于这些原因中的一个或其他原因,真实客户端的安全上下文与服务主机的安全上下文不一致。

于 2012-06-29T21:23:03.420 回答
7

如果搜索此错误并遇到此帖子,则解决此根本问题的另一种可能性 - 如果您收到net.pipe在您的 url 中找不到地址的错误(即http://localhost:1234/MyService/etc/),请确保Net.Pipe 侦听器适配器Windows 服务已启动。(我也启动了 Net.Tcp Listener Adapter)

在某些情况下,该服务似乎没有启用或启动,尤其是在部署到可能没有安装大量积极使用这些服务的开发工具的远程服务器时。启动服务解决了这个问题。

于 2013-03-28T20:22:50.383 回答
3

您的客户端使用的端点必须与您的 WCF 服务公开的端点相匹配。这意味着指定客户端端点的地址/绑定/合约元组必须与 WCF 服务公开的端点的地址/绑定/合约元组完全匹配。如果您使用的是 app.config 方法,请确保 WCF 服务和客户端配置文件中的所有内容都拼写正确。如果您以编程方式添加端点,请确保您没有拼错代码中的任何内容。

于 2009-12-04T20:01:10.047 回答