WCF NamedPipe CommunicationException - "Труба была завершена (109, 0x6d)".
Я пишу службу Windows с сопроводительным "средством определения состояния". Служба содержит WCF с именем pipe endpoint для межпроцессного взаимодействия. Через именованный канал инструмент состояния может периодически запрашивать службу для последнего "статуса".
![enter image description here]()
На моей машине разработки у меня есть несколько IP-адресов; одна из них - "локальная" сеть с адресом 192.168.1.XX. Другая - "корпоративная" сеть с адресом 10.0.X.XX. Служба Windows собирает многоадресный трафик UDP на одном IP-адресе.
Служба 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)."
Теперь я не думаю, что IP-адрес UDP-клиента должен был иметь какое-либо отношение к функциональности интерфейса Named-Pipe; они являются полностью отдельными частями приложения!
Вот соответствующие разделы конфигурации WCF:
//On the Client app:
string myNamedPipe = "net.pipe://127.0.0.1/MyNamedPipe";
ChannelFactory<IMyService> proxyFactory =
new ChannelFactory<IMyService>(
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();
Я бы не подумал, что это проблема с правами доступа - я запускаю клиент с правами администратора, но, возможно, существует какая-то причина в домене?
Ответы
Ответ 1
IP-адрес был, оказывается, полной красной селедкой.
Настоящая причина исключения недействительна. Значения перечисления возвращаются службой WCF.
Мое перечисление было определено следующим образом:
[DataContract]
public enum MyEnumValues : Byte
{
[EnumMember]
Enum1 = 0x10,
[EnumMember]
Enum2 = 0x20,
[EnumMember]
Enum3 = 0x30,
[EnumMember]
Enum4 = 0x40,
}
Он отлично выглядит на поверхности.
Но сырой статус, сообщенный базовой службой, был байтовым значением "0", и не было соответствующего значения Enum, для которого оно было выполнено.
Как только я убедился, что значения Enum были действительны, инструмент загорелся, как рождественская елка.
Если вы сомневаетесь, предположите, что ваши данные WCF недействительны.
Ответ 2
Имел ту же проблему There was an error reading from the pipe: Unrecognized error 109 (0x6d).
- Одна из причин заключалась в несогласованном привязке между клиентом и сервером
<netNamedPipeBinding> <security mode="None"></security>...
(без связи)
- Другой прерывистый вопрос связан с тайм-аутом.
Оба имеют то же самое верхнее сообщение об ошибке.
Увеличение времени при пересылке сервера и клиента перестало возникать из-за повторного появления.
Время пересылки, которое было установлено слишком низко:
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)
Ответ 3
Иногда эта ошибка вызвана полиморфной особенностью объектов. например, следующий метод обслуживания возвращает список лиц:
[OperationContract]
List<Person> GetEmployee();
если у нас есть класс Supervisor, унаследованный от класса Person, и указанный выше метод пытается вернуть объект Supervisor, класс сериализатора WCF не может интерпретировать ответ, поэтому эта ошибка будет поднята.
Решение этой проблемы состоит в том, чтобы использовать известные типы " или " известных типов услуг. мы должны указать, что неявные объекты могут взаимодействовать с использованием метода или службы.
Для моего примера мы можем поместить атрибут ServiceKnownType в объявление метода или службы как следующий код:
[OperationContract]
[ServiceKnownType(typeof(Supervisor))]
List<Person> GetEmployee();
Ответ 4
Это исключение означает, что на стороне сервера существует проблема сериализации.
Эта проблема может быть решена путем поиска в файле трассировки (svclog). Чтобы включить трассировку, используйте следующую конфигурацию:
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="false">
<listeners>
<add name="traceListener" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="traceListener" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\Remos\Log\WcfTraceServer.svclog" />
</sharedListeners>
</system.diagnostics>
В моем случае я сериализую значение, которое не было в перечислении.
Ответ 5
Я получил эту ошибку, когда была запущена служебная операция, и канал был фактически неисправен. В вашем случае вы уже проверили, что операция обслуживания как таковая выполнена правильно, и только обратная передача бросила, но если есть сомнения, убедитесь, что операция службы работает нормально.
Ответ 6
Это произошло в моей службе WCF, когда возвращаемая полезная нагрузка была слишком большой. Исправлено, добавив это в serviceBehavior в app.config:
<dataContractSerializer maxItemsInObjectGraph="[some big number]" />
Ответ 7
У меня было много свойств без набора {} в нем. Добавив это, я решил проблему.
Ответ 8
Такая же проблема, но решена благодаря Wojciech .
Мне пришлось немного поработать, чтобы найти, где положить тег <security>
, вот как выглядит начало раздела system.serviceModel...
<system.serviceModel>
<bindings>
<netNamedPipeBinding>
<binding>
<security mode="None"></security>
</binding>
</netNamedPipeBinding>
</bindings>
....