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>
   ....