WCF NamedPipe CommunicationException – “管道已结束。 (109,0x6d)。“

我正在编写带有“状态工具”的Windows服务。 该服务托管一个名为管道端点的WCF,用于进程间通信。 通过命名管道,状态工具可以定期查询服务以获取最新的“状态”。

在此处输入图像描述

在我的开发机器上,我有多个IP地址; 其中一个是具有192.168.1.XX地址的“本地”网络。 另一个是“公司”网络,具有10.0.X.XX地址。 Windows服务在单个IP地址上收集UDP多播流量。

到目前为止,Windows服务只要使用“192.168.1.XX”地址就可以正常工作。 它始终正确地向客户报告状态。

一旦我切换到另一个“公司”IP地址(10.0.X.XX)并重新启动服务,我在检索状态时会得到连续的“CommunicationExceptions”:

"There was an error reading from the pipe: The pipe has been ended. (109, 0x6d)." 

现在,我不认为UDP客户端的“声明的”IP地址应该与Named-Pipe接口的function有关; 它们完全是应用程序的独立部分!

以下是相关的WCF配置部分:

 //On the Client app: string myNamedPipe = "net.pipe://127.0.0.1/MyNamedPipe"; ChannelFactory proxyFactory = new ChannelFactory( new NetNamedPipeBinding(), new EndpointAddress(myNamedPipe)); //On the Windows Service: string myNamedPipe = "net.pipe://127.0.0.1/MyNamedPipe"; myService = new MyService(myCustomArgs); serviceContractHost = new ServiceHost(myService ); serviceContractHost.AddServiceEndpoint( typeof(IMyService), new NetNamedPipeBinding(), myNamedPipe); serviceContractHost.Open(); 

我不认为这是一个“权限”问题 – 我正在运行具有管理权限的客户端 – 但也许有一些特定于域的原因导致了这一点?

事实certificate,IP地址是一个完整的红色鲱鱼。

exception的真正原因是WCF服务返回了无效的Enum值。

我的枚举如此定义:

 [DataContract] public enum MyEnumValues : Byte { [EnumMember] Enum1 = 0x10, [EnumMember] Enum2 = 0x20, [EnumMember] Enum3 = 0x30, [EnumMember] Enum4 = 0x40, } 

表面看起来很好。

但是底层服务报告的原始状态是字节值“0”,并且没有相应的Enum值可以对其进行强制转换。

一旦我确保Enum值全部有效,该工具就像圣诞树一样点亮。

如有疑问,请假设您的WCF数据无效。

有相同的问题There was an error reading from the pipe: Unrecognized error 109 (0x6d).

  • 一个原因是客户端和服务器之间的绑定不一致 ... (没有通信)
  • 另一个间歇性问题是超时问题。

两者都有相同的顶部错误消息。

增加服务器和客户端绑定的时间会使问题再次出现。

绑定时间设置得太低:

 sendTimeout="00:00:05" receiveTimeout="00:00:05" 

堆栈跟踪: at System.ServiceModel.Channels.StreamConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) at System.ServiceModel.Channels.SessionConnectionReader.Receive(TimeSpan timeout) at System.ServiceModel.Channels.SynchronizedMessageSource.Receive(TimeSpan timeout) at System.ServiceModel.Channels.TransportDuplexSessionChannel.Receive(TimeSpan timeout) at System.ServiceModel.Channels.TransportDuplexSessionChannel.TryReceive(TimeSpan timeout, Message& message) at System.ServiceModel.Dispatcher.DuplexChannelBinder.Request(Message message, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) at System.ServiceModel.Channels.StreamConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) at System.ServiceModel.Channels.SessionConnectionReader.Receive(TimeSpan timeout) at System.ServiceModel.Channels.SynchronizedMessageSource.Receive(TimeSpan timeout) at System.ServiceModel.Channels.TransportDuplexSessionChannel.Receive(TimeSpan timeout) at System.ServiceModel.Channels.TransportDuplexSessionChannel.TryReceive(TimeSpan timeout, Message& message) at System.ServiceModel.Dispatcher.DuplexChannelBinder.Request(Message message, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

有时这个错误是由对象的多态特征引起的。 例如,以下service的方法将返回人员列表:

 [OperationContract] List GetEmployee(); 

如果我们有inheritance自Person类的Supervisor类,并且上面的方法尝试返回Supervisor对象, 则WCF序列化器类无法解释响应,因此会引发此错误
该问题的解决方案是使用“已知类型”“服务已知类型” 。 我们必须指定隐式对象可以使用方法或服务进行交互。 对于我的示例,我们可以将ServiceKnownType属性放在方法或服务声明中,如下代码:

 [OperationContract] [ServiceKnownType(typeof(Supervisor))] List GetEmployee(); 

此exception意味着服务器端存在序列化问题。

可以通过查看跟踪文件(svclog)来解决此问题。 要打开跟踪,请使用以下配置:

                  

在我的情况下,我正在序列化一个不在枚举中的值。

当返回的有效负载太大时,这发生在我的WCF服务中。 通过在app.config中的serviceBehavior中添加它来修复它:

  

当服务操作抛出并且通道实际出现故障时,我收到此错误。 在您的情况下,您已经validation了服务操作正确完成并且只返回了投票,但如果有疑问,请确保服务操作运行正常。

我有很多属性没有设置{}。 添加这个解决了我的问题。

同样的问题,但由于Wojciech的回答解决了 。

我不得不做更多的挖掘以找到放置标记的位置,所以这里是system.serviceModel部分的开始现在看起来…

         .... 

我有这个问题,因为我使用的是较旧的教程 ,并尝试以编程方式进行配置。

我缺少的部分是提供元数据端点( 谢谢,这篇文章! )。

 ServiceMetadataBehavior serviceMetadataBehavior = host.Description.Behaviors.Find(); if (serviceMetadataBehavior == null) { serviceMetadataBehavior = new ServiceMetadataBehavior(); host.Description.Behaviors.Add(serviceMetadataBehavior); } host.AddServiceEndpoint( typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexNamedPipeBinding(), "net.pipe://localhost/PipeReverse/mex" );