问题描述
我是WCF服务的开发人员。我的测试客户工作得很好。但是当涉及真实的客户端(使用相同的客户端代理)时,它会失败。相同的WCF服务与netTcpBinding一起使用,此错误仅在使用netNamedPipeBinding时发生,即使使用ConcurrencyMode = ConcurrencyMode.Single这是例外
服务器堆栈跟踪:at
内部异常
堆栈跟踪显示客户端WCF通道堆栈尝试从服务URL导出服务使用的命名管道的实际名称时失败。该服务通过在,其中包含GUID作为其字段之一。用于共享内存部分的名称是通过应用一个编译为NetNamedPipeBinding的服务器端和客户端WCF代码的算法从服务URL导出的。
在问题中报告的异常真的意味着已经将该算法应用于服务URL以获得名称,客户端代码无法打开该名称的共享内存部分的句柄。这可能意味着异常消息声明,没有服务侦听用于导出名称的服务URL。但是这可能意味着内存部分在那里,服务也是如此,但客户端代码没有运行在安全上下文中,允许它访问共享内存。
在Vista之前的Windows平台上,WCF客户端绝对不可能缺少打开共享内存的安全权限,从中读取管道名称GUID,然后成功连接到服务的管道。但是在Vista和更高版本的平台上有新的安全机制,这使得它成为一个更常见的故障情况。
Vista为命名的内核对象引入了不同命名空间的概念:全局(机器范围)的命名空间和每个登录会话的私有命名空间。当查找通告管道名称的共享内存部分时,NetNamedPipeBinding客户端代码将尝试两个命名空间。如果服务器使用全局名称创建共享内存,或者服务和客户端在同一登录会话中运行,那么客户端将找到它正在查找的内容。但是,如果服务无法在全局命名空间中创建一个对象(它始终尝试首先执行此操作),那么它将返回创建私有会话命名空间,然后只有在同一会话中运行的客户端才能看到它。创建全局命名空间内核对象需要在Vista和更高版本的平台中提供特殊权限,通常只有运行As Administrator的Windows服务进程和应用程序才能运行。一个常见的缺陷是尝试在Windows服务中创建一个客户端,尝试连接到在交互式用户会话中运行的应用程序中托管的WCF NetNamedPipe服务。
Vista如果客户端代码运行在较低的完整性上下文(例如浏览器插件)中,则强制完整性机制也可以阻止假定客户端连接到WCF NetNamedPipeBinding服务。
我想象,问题中报告的症状,测试客户端工作,但真正的客户端不工作,几乎肯定是由于真实客户端与服务主机的安全上下文不一致造成的,一个或其他这些原因。
I am the developer of a WCF service. My test clients work very well with it. But when it comes to real clients (using the same client proxy), it fails. The same WCF service works with netTcpBinding, this error occurs only with netNamedPipeBinding, even with ConcurrencyMode = ConcurrencyMode.Single
Here is the exception
Server stack trace: at
Inner Exception
The stack trace shows that the client-side WCF channel stack failed when trying to derive from the service URL the actual name of the named pipe being used by the service. The service publishes the pipe name (which is a GUID which changes each time the service restarts) by placing a small structure in a named shared memory section which contains the GUID as one of its fields. The name used for the shared memory section is derived from the service URL by applying an algorithm which is compiled into both the server-side and client-side WCF code for the NetNamedPipeBinding.
The exception reported in the question really means that having applied the algorithm to the service URL to come up with a name, the client side code could not open a handle to a shared memory section of that name. This may mean, as the exception message states, that there is no service listening on the service URL used to derive the name. But it can instead mean that the memory section is there, and so is the service, but the client-side code is not running in a security context which allows it to access the shared memory.
On Windows platforms prior to Vista it is fairly unlikely that a WCF client would ever lack the security permissions to open the shared memory, read the pipe name GUID from it, and then successfully connect to the service's pipe. But on Vista and later platforms there are new security mechanisms which make this a much more common failure scenario.
Vista introduced a concept of different namespaces for named kernel objects: there is a Global (machine-wide) namespace, and a Private namespace for each logon session. The NetNamedPipeBinding client code will try both namespaces when looking for the shared memory section which advertises the pipe name. If the server has created the shared memory using a Global name, or if the service and the client are running in the same logon session, then the client will find what it is looking for. If, though, the service cannot create an object in the Global namespace (it always tries to do this first) then it will fall back to creating it the private session namespace, and then only clients running in the same session will be able to see it. Creating Global namespace kernel objects requires a special privilege in Vista and later platforms, which typically only Windows Service processes and applications running "As Administrator" will have. A common pitfall is to try to create a client in a Windows Service attempting to connect to a WCF NetNamedPipe service hosted in an application running in the interactive user session.
The Vista Mandatory Integrity Mechanism can also prevent a putative client connecting to a WCF NetNamedPipeBinding service, if the client code is running in a lower integrity context (e.g. a browser plug-in) than the code hosting the service.
I would imagine that the symptoms reported in the question, with test clients working but real clients not working, are almost certainly caused by the security context of the real clients being inconsistent with that of the service host, for one or other of these reasons.
这篇关于使用WCF netNamedPipeBinding时,未找到命名管道的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!