2013-04-05 4 views
13

Ich schreibe einen Windows-Dienst mit begleitenden "Status-Tool". Der Dienst hostet einen WCF-Pipe-Endpunkt für die Kommunikation zwischen Prozessen. Über die Named Pipe kann das Status-Tool den Dienst regelmäßig nach dem letzten "Status" abfragen.WCF NamedPipe CommunicationException - "Die Pipe wurde beendet. (109, 0x6d)."

enter image description here

Auf meiner Entwicklung Maschine, ich mehrere IP-Adressen haben; Einer von ihnen ist ein "lokales" Netzwerk mit einer Adresse 192.168.1.XX. Das andere ist das "Firmennetzwerk" mit einer 10.0.X.XX-Adresse. Der Windows-Dienst sammelt UDP-Multicast-Datenverkehr für eine einzelne IP-Adresse.

Der Windows-Dienst hat bis jetzt funktioniert, solange er die Adresse "192.168.1.XX" verwendet. Es meldet den Status regelmäßig korrekt an den Client.

Sobald ich auf der anderen Seite "Corporate" IP-Adresse (10.0.X.XX) und neu gestartet wird den Dienst eingeschaltet, erhalte ich kontinuierlich "CommunicationExceptions" beim Abrufen des Status:

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

Jetzt, Ich würde nicht denken, dass die "beanspruchte" IP-Adresse des UDP-Clients irgendetwas mit der Funktionalität der Named-Pipe-Schnittstelle zu tun haben sollte; Sie sind völlig separate Teile der Anwendung!

Hier sind die relevanten WCF-Konfigurations Sektionen:

//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(); 

Ich würde nicht denken, dies ist Thema einer ‚Berechtigungen‘ - Ich bin den Client mit Administratorrechten ausgeführt wird - aber vielleicht gibt es einige domänenspezifischen Grund das ist kaputt gegangen?

+0

Wie sieht die Ausnahmestapelüberwachung aus? Bist du * sicher * nichts anderes? Haben Sie nach dem Wechsel der Servicekonfiguration das Statustool neu gestartet? Könnten Sie den Teil Ihres Status Tool-Codes posten, der Ihren rpoxy instanziiert und den WCF-Aufruf auslöst? –

+0

Ich werde die Frage am Montag aktualisieren, wenn ich wieder an die Arbeit komme.Ein Freund schlug auch vor, dass die IP-Adresse ein Ablenkungsmanöver sein könnte, und der wirkliche Unterschied könnte der Rückgabewert bestimmter Enums sein. Ich werde das auch untersuchen. – BTownTKD

Antwort

9

Die IP-Adresse war, es stellt sich heraus, eine komplette Hering.

Der eigentliche Grund für die Ausnahme waren ungültige Enum-Werte, die vom WCF-Dienst zurückgegeben wurden.

Meine Enum wurde thusly definiert:

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

Es ist auf der Oberfläche sieht gut aus.

Der vom zugrunde liegenden Service gemeldete unbearbeitete Status war jedoch ein Byte-Wert von "0", und es gab keinen entsprechenden Enum-Wert, für den er umgewandelt werden konnte.

Sobald ich sichergestellt hatte, dass die Enum-Werte alle gültig waren, leuchtete das Werkzeug wie ein Weihnachtsbaum auf.

Nehmen Sie im Zweifelsfall an, dass Ihre WCF-Daten ungültig sind.

+0

Gab es irgendwas in den Tracing-Dateien, das darauf hinwies oder sind wir mit einem generischen "Pipe wurde beendet" -Fehler fest und müssen den gesamten betroffenen Code scannen, um hoffentlich das mögliche Serialisierungsproblem zu finden? –

+3

Ich musste alle Daten scannen und manuell überprüfen. Ich hoffe, du hast mehr Glück mit hilfreichen Spuren! – BTownTKD

+0

"Nehmen Sie im Zweifelsfall an, dass Ihre WCF-Daten ungültig sind." - hat meinen Tag gerettet :) – Yaniv

1

Ich habe diesen Fehler, wenn die Serviceoperation warf und der Kanal tatsächlich fehlerhaft war. In Ihrem Fall haben Sie bereits verifiziert, dass der Servicevorgang als solcher ordnungsgemäß ausgeführt wurde und nur die Rückgabe ausgelöst wurde. Wenn jedoch Zweifel bestehen, stellen Sie sicher, dass der Servicevorgang ordnungsgemäß ausgeführt wird.

2

haben das gleiche Problem There was an error reading from the pipe: Unrecognized error 109 (0x6d).

  • Ein Grund inkonsistent Bindung zwischen Client und Server im Zusammenhang <netNamedPipeBinding> <security mode="None"></security>... (keine Kommunikation)
  • Das andere intermittierende Problem waren Time-out war.

Beide hatten die gleiche Top-Fehlermeldung.

Erhöhung der Timeout in der Server-und Client-Bindung beendet Problem von wieder angezeigt.

Bindung Zeit darauf hin, dass zu niedrig eingestellt wurde:

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

Stapelüberwachung: 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

Dies geschah in meinem WCF-Dienst, wenn die Nutzlast war zu groß zurückgegeben. Behebt es durch Hinzufügen in einem ServiceBehavior in app.config:

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

Manchmal dieser Fehler durch polymorphe Eigenschaft von Objekten verursacht. zum Beispiel folgenden Service-Methode Liste der Personen zurück:

[OperationContract] 
List<Person> GetEmployee(); 

wenn wir Supervisor-Klasse geerbt von Person-Klasse, und das obige Verfahren versucht zurückzukehren Supervisor-Objekt haben, die WCF Serializer Klasse die Antwort nicht interpretieren kann, so Dieser Fehler wird ausgelöst.
Die Lösung für dieses Problem ist die Verwendung "bekannten Typen" oder "Service bekannten Typen". Wir müssen angeben, dass implizite Objekte mit Methoden oder Services interagieren können. Für mein Beispiel können wir ServiceKnownType Attribut in Verfahren oder eine Dienstleistung Erklärung wie folgenden Code setzen:

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

Diese Ausnahme bedeutet, dass es ein Problem der Serialisierung auf der Server-Seite ist.

Dieses Problem kann durch einen Blick in die Trace-Datei (svclog) gelöst werden. So aktivieren Sie die Verwendung Tracing die folgende Konfiguration:

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

In meinem Fall war ich Serialisierung einen Wert, der nicht in der ENUM war.

1

Ich hatte viele Eigenschaften ohne set {} drin. Das Hinzufügen dieses Problems löste mein Problem.

0

Gleiches Problem aber gelöst dank Wojciech 's answer.

Ich hatte ein bisschen mehr zu tun zu graben, wo zu finden, den <security> Tag gelegt, so ist hier, wie der Beginn des system.serviceModel Abschnitts jetzt sieht ...

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

ich, weil ich dieses Problem hatte benutzte einen older tutorial und versuchte, programmatisch zu konfigurieren.

Der Teil, den ich fehlte, war die Bereitstellung des Metadaten-Endpunkts (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" 
);