2013-04-05 3 views
13

Я пишу службу Windows с сопровождающим «средством определения состояния». Служба содержит WCF с именем pipe endpoint для межпроцессного взаимодействия. Через именованный канал инструмент состояния может периодически запрашивать службу для последнего «статуса».WCF NamedPipe CommunicationException - «Труба завершена (109, 0x6d)».

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-адрес U утверждаемого клиента должен иметь какое-либо отношение к функциональности интерфейса 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(); 

Я не думаю, что это вопрос «разрешение» - я бег клиента с правами администратора - но, возможно, есть некоторая область конкретных причины это сломалось?

+0

Как выглядит трассировка стека исключений? Вы уверены, что ничего не изменилось? Вы перезапустили инструмент состояния после переключения конфигурации службы? Не могли бы вы разместить часть кода Status Tool, которая создает экземпляр вашего rpoxy и вызывает вызов WCF? –

+0

Я обновлю вопрос в понедельник, когда вернусь к работе.Друг также предположил, что IP-адрес может быть красной селедкой, и реальная разница может быть возвратной величиной конкретных Enums. Я также исследую это. – BTownTKD

ответ

9

Адрес IP был, оказывается, полной красной селедкой.

Настоящая причина исключения недействительна. Возвращаемые значения возвращаются службой WCF.

Мой перечисление было определено таким образом:

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

Он прекрасно смотрится на поверхности.

Но сырой статус, сообщенный базовой службой, был байтовым значением «0», и не было соответствующего значения Enum, для которого его можно было отличить.

Как только я убедился, что значения Enum были действительны, инструмент загорелся, как рождественская елка.

Если вы сомневаетесь, предположите, что данные вашего WCF недействительны.

+0

Было ли что-нибудь в файлах трассировки, которые указывали на это, или мы застряли с общей ошибкой «pipe was been end» и вам нужно отсканировать весь код, чтобы надеяться найти возможную проблему сериализации? –

+3

Мне пришлось сканировать все данные и проверить их вручную. Надеюсь, вам повезет с полезными следами! – BTownTKD

+0

«Если вы сомневаетесь, предположите, что данные вашего WCF недействительны». - спас мой день :) – Yaniv

1

Я получил эту ошибку при срабатывании сервисной операции и фактически был поврежден канал. В вашем случае вы уже подтвердили, что операция обслуживания как таковая выполнена правильно, и только возврат был брошен, но если есть сомнения, убедитесь, что операция службы работает нормально.

2

была такая же проблема There was an error reading from the pipe: Unrecognized error 109 (0x6d).

  • Одной из причин было несовместимым связывания между клиентом и сервером <netNamedPipeBinding> <security mode="None"></security>... (нет связи)
  • Другой прерывистый выпуск был тайм-аут связаны между собой.

Оба имеют такое же верхнее сообщение об ошибке.

Увеличение тайм-аут при пересылке сервера и клиента прекратил выпуск после повторного появления.

время Binding, что был установлен слишком низко:

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

Stack след: 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)

1

Это произошло в моей службы WCF, когда полезная нагрузка возвращается была слишком большой. Исправлено, добавив это в serviceBehavior в app.config:

<dataContractSerializer maxItemsInObjectGraph="[some big number]" /> 
2

Иногда эта ошибка вызвана полиморфной особенностью объектов. например, следующий метод сервиса будет возвращать список лиц:

[OperationContract] 
List<Person> GetEmployee(); 

если мы Supervisor класс наследуется от класса Person, и вышеупомянутый способ попытаться вернуть супервизор объект, класса сериализатору WCF не может интерпретировать ответ, так эта ошибка будет поднята.
Решение этой проблемы заключается в использовании «известных типов» или «сервис известных типов». мы должны указать, что неявные объекты могут взаимодействовать с использованием метода или службы. Для моего примера, мы можем поставить атрибут ServiceKnownType в методе или декларации службы, как следующий код:

[OperationContract] 
[ServiceKnownType(typeof(Supervisor))] 
List<Person> GetEmployee(); 
2

Это исключение означает, что существует проблема сериализации на стороне сервера.

Эта проблема может быть решена путем поиска в файле трассировки (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> 

В моем случае я сериализация значения, которое не было в перечислении.

1

У меня было много свойств без набора {} в нем. Добавив это, я решил проблему.

0

Такая же проблема, но решена благодаря Wojciechanswer.

я должен был сделать немного более копать, чтобы найти, где поставить <security> тег так вот как начало раздела system.serviceModel выглядит сейчас ...

<system.serviceModel> 
    <bindings> 
    <netNamedPipeBinding> 
     <binding> 
     <security mode="None"></security> 
     </binding> 
    </netNamedPipeBinding> 
    </bindings> 
    .... 
0

Я имел этот вопрос, потому что я использовал older tutorial и пытался настроить программно.

Часть, которую я отсутствовала, заключалась в предоставлении конечной точки метаданных (thank you, this post!).

ServiceMetadataBehavior serviceMetadataBehavior = 
    host.Description.Behaviors.Find<ServiceMetadataBehavior>(); 

if (serviceMetadataBehavior == null) 
{ 
    serviceMetadataBehavior = new ServiceMetadataBehavior(); 
    host.Description.Behaviors.Add(serviceMetadataBehavior); 
} 

host.AddServiceEndpoint(
    typeof(IMetadataExchange), 
    MetadataExchangeBindings.CreateMexNamedPipeBinding(), 
    "net.pipe://localhost/PipeReverse/mex" 
); 
Смежные вопросы