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

时间:2009-12-04 18:25:39

标签: .net wcf exception netnamedpipebinding

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

也是如此

这是例外

  

没有终点收听   net.pipe://本地主机/为MyService   那可以接受这个消息。这是   通常由不正确的地址引起   或SOAP动作。请参阅InnerException,if   目前,了解更多详情。

服务器堆栈跟踪:位于

  

System.ServiceModel.Channels.PipeConnectionInitiator.GetPipeName(URI   uri)at   System.ServiceModel.Channels.NamedPipeConnectionPoolRegistry.NamedPipeConnectionPool.GetPoolKey(的EndpointAddress   地址,Uri via)at   System.ServiceModel.Channels.CommunicationPool`2.TakeConnection(的EndpointAddress   地址,Uri via,TimeSpan超时,   TKEY的&安培;关键)at   System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(时间跨度   超时)at   System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(时间跨度   超时)at   System.ServiceModel.Channels.CommunicationObject.Open(时间跨度   超时)at   System.ServiceModel.Channels.ServiceChannel.OnOpen(时间跨度   超时)at   System.ServiceModel.Channels.CommunicationObject.Open(时间跨度   超时)at   System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(时间跨度   超时,CallOnceManager级联)
  在   System.ServiceModel.Channels.ServiceChannel.EnsureOpened(时间跨度   超时)at   System.ServiceModel.Channels.ServiceChannel.Call(字符串   动作,布尔单向,   ProxyOperationRuntime操作,   Object [] ins,Object [] outs,TimeSpan   超时)at   System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage   methodCall,ProxyOperationRuntime   操作)   System.ServiceModel.Channels.ServiceChannelProxy.Invoke(即时聊天   消息)

     

在[0]处重新抛出异常:at   System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(即时聊天   reqMsg,IMessage retMsg)at   System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&安培;   

的msgData,Int32类型)

内部异常

  

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

3 个答案:

答案 0 :(得分:21)

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

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

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

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

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

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

答案 1 :(得分:5)

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

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

答案 2 :(得分:3)

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