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

发布于 2024-08-14 08:39:28 字数 1947 浏览 1 评论 0原文

我是 WCF 服务的开发人员。我的测试客户用它工作得很好。但是当涉及到真实的客户端(使用相同的客户端代理)时,它会失败。相同的 WCF 服务与 netTcpBinding 配合使用,此错误仅在使用 netNamedPipeBinding 时发生,即使使用 ConcurrencyMode = ConcurrencyMode.Single

这里是例外

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

服务器堆栈跟踪:位于

System.ServiceModel.Channels.PipeConnectionInitiator.GetPipeName(Uri 乌里)在 System.ServiceModel.Channels.NamedPipeConnectionPoolRegistry.NamedPipeConnectionPool.GetPoolKey(EndpointAddress 地址,Uri 通过)在 System.ServiceModel.Channels.CommunicationPool`2.TakeConnection(EndpointAddress 地址、Uri via、TimeSpan 超时、 TKey&键)在 System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(时间跨度 超时)在 System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan 超时)在 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan 超时)在 System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan 超时)在 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan 超时)在 System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan 超时,CallOnceManager级联)
在 System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan 超时)在 System.ServiceModel.Channels.ServiceChannel.Call(字符串 动作,布尔单向, ProxyOperation运行时操作, 对象 [] 输入、对象 [] 输出、TimeSpan 超时)在 System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage 方法调用、代理操作运行时 操作)在 System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage 消息)

在 [0] 处重新抛出异常:at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg、IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData,Int32 类型)位于

内部异常

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

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

There was no endpoint listening at
net.pipe://localhost/MyService
that could accept the message. This is
often caused by an incorrect address
or SOAP action. See InnerException, if
present, for more details.

Server stack trace: at

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) at
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan
timeout) at
System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan
timeout, CallOnceManager cascade)
at
System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan
timeout) at
System.ServiceModel.Channels.ServiceChannel.Call(String
action, Boolean oneway,
ProxyOperationRuntime operation,
Object[] ins, Object[] outs, TimeSpan
timeout) at
System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage
methodCall, ProxyOperationRuntime
operation) at
System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage
message)

Exception rethrown at [0]: at
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage
reqMsg, IMessage retMsg) at
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&
msgData, Int32 type) at

Inner Exception

PipeException: "The pipe endpoint 'net.pipe://localhost/MyService' could not be found on your local machine. "

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甩你一脸翔 2024-08-21 08:39:28

堆栈跟踪显示,尝试从服务 URL 派生服务所使用的命名管道的实际名称时,客户端 WCF 通道堆栈失败。该服务通过在 命名共享内存部分,其中包含 GUID 作为其字段之一。用于共享内存部分的名称是通过应用一种算法从服务 URL 派生的,该算法被编译到 NetNamedPipeBinding 的服务器端和客户端 WCF 代码中。

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

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

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

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

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

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.

七度光 2024-08-21 08:39:28

如果搜索此错误并遇到此帖子,则可以解决此根本问题 - 如果您收到错误消息,表明在您的 url 中找不到 net.pipe 地址(即 http: //localhost:1234/MyService/etc/) 确保 Net.Pipe Listener Adapter Windows 服务已启动。 (我还启动了 Net.Tcp Listener Adapter)

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

Another possibility to fix this root issue if searching for this error and coming across this post - if you are getting an error that no net.pipe address can be found at your url (i.e. http://localhost:1234/MyService/etc/) make sure that the Net.Pipe Listener Adapter Windows Service is started. (I also started Net.Tcp Listener Adapter)

The service does not seem to be enabled or started in some scenarios especially when deploying out to a remote server that might not of had a lot of the development tools installed that actively use these services. Starting the service fixed the issue.

未蓝澄海的烟 2024-08-21 08:39:28

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

The endpoint used by your client has to match an endpoint exposed by your WCF service. This means that the address/binding/contract tuple of the specified client endpoint must exactly match the address/binding/contract tuple of an endpoint exposed by your WCF service. If you'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 misspelled anything in the code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文