首页 文章

使用WCF netNamedPipeBinding时找不到命名管道

提问于
浏览
7

我是WCF服务的开发人员 . 我的测试客户工作得很好 . 但是当谈到真正的客户端(使用相同的客户端代理)时,它就失败了 . 相同的WCF服务与netTcpBinding一起使用,只有netNamedPipeBinding才会出现此错误,即使使用ConcurrencyMode = ConcurrencyMode.Single也是如此 .

这是例外

net.pipe:// localhost / MyService上没有可以接受该消息的 endpoints . 这通常是由错误的地址或SOAP操作引起的 . 有关更多详细信息,请参阅InnerException(如果存在) .

服务器堆栈跟踪:at

System.ServiceModel.CamedConnectionPoolRegistry.NamedPipeConnectionPool.GetPoolKey(EndpointAddress地址,Uri via)上的System.ServiceModel.Channels.PipeConnectionInitiator.GetPipeName(Uri uri)位于System.ServiceModel.Channels.CommunicationPool`2.TakeConnection(EndpointAddress地址,Uri)在System.ServiceModel .Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan超时)的System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan超时)处的System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan超时)处的通过,TimeSpan超时,TKey和密钥) System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)在System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)处于System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout,CallOnceManager cascade)的System处 . System.ServiceModel.Channels.ServiceChannel.Call(String actio)中的ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout) n,布尔单向,ProxyOperationRuntime操作,Object [] ins,Object []出,TimeSpan超时)System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall,ProxyOperationRuntime操作)在System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage)消息)在[0]处重新抛出异常:在System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,IMessage retMsg)处于System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&msgData,Int32 type)at at

内在例外

PipeException:“在本地计算机上找不到管道 endpoints 'net.pipe:// localhost / MyService' . ”

3 回答

  • 4

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

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

    在Vista之前的Windows平台上,WCF客户端不太可能缺乏打开共享内存的安全权限,从中读取管道名称GUID,然后成功连接到服务的管道 . 但是在Vista和后来的平台上,有一些新的安全机制使这成为一种更常见的故障情况 .

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

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

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

  • 19

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

    在某些情况下,似乎没有启用或启动该服务,尤其是在部署到可能没有安装许多主动使用这些服务的开发工具的远程服务器时 . 启动服务修复了问题 .

  • 3

    客户端使用的 endpoints 必须与WCF服务公开的 endpoints 匹配 . 这意味着指定客户端 endpoints 的地址/绑定/ Contract 元组必须与WCF服务公开的 endpoints 的地址/绑定/ Contract 元组完全匹配 . 如果你're using the app.config approach, make sure everything is spelled correctly in both the WCF service and client config files. If you are adding the endpoints programmatically, make sure you haven' t拼错了代码中的任何内容 .

相关问题