2013-04-05 16 views
13

Sto scrivendo un servizio di Windows con "strumento di stato" di accompagnamento. Il servizio ospita un endpoint di pipe denominato WCF per la comunicazione tra processi. Attraverso la named pipe, lo status tool può interrogare periodicamente il servizio per l'ultimo "status".WCF NamedPipe CommunicationException - "Il pipe è stato terminato. (109, 0x6d)."

enter image description here

Sulla mia macchina di sviluppo, non ho più indirizzi IP; uno di questi è una rete "locale" con indirizzo 192.168.1.XX. L'altra è la rete "aziendale", con un indirizzo 10.0.X.XX. Il servizio Windows raccoglie il traffico multicast UDP su un singolo indirizzo IP.

Il servizio di Windows ha funzionato fino a ora fino a quando utilizza l'indirizzo "192.168.1.XX". Segnala costantemente lo stato correttamente al client.

Non appena sono passato ad un altro, Indirizzo IP "corporate" (10.0.X.XX) e riavviato il servizio, ottengo continui "CommunicationExceptions" durante il recupero dello stato:

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

Ora, Non penserei che l'indirizzo IP "richiesto" del client UDP debba avere nulla a che fare con la funzionalità dell'interfaccia Named-Pipe; sono pezzi completamente separati dell'applicazione!

Qui ci sono le pertinenti sezioni di configurazione 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(); 

non vorrei che questo sia un problema di 'permessi' - Io corro il cliente con privilegi di amministratore - ma forse c'è una ragione specifica del dominio questo è rotto?

+0

Che aspetto ha la traccia dello stack di eccezioni? Sei * sicuro * nient'altro è cambiato? Hai riavviato lo Strumento di stato dopo aver cambiato la configurazione del servizio? Potresti pubblicare la parte del tuo codice di Status Tool che istanzia il tuo rpoxy e fa la chiamata alla WCF? –

+0

Aggiornerò la domanda lunedì, quando torno al lavoro.Un amico ha anche suggerito che l'indirizzo IP potrebbe essere una falsa pista, e la vera differenza potrebbe essere il valore di ritorno di particolari enumerazioni. Lo esaminerò anche io. – BTownTKD

risposta

9

L'indirizzo IP era, si scopre, una falsa pista completa.

Il vero motivo dell'eccezione non era valido per i valori Enum restituiti dal servizio WCF.

mio enum è stata definita nel seguente modo:

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

Si guarda bene sulla superficie.

Ma lo stato non elaborato segnalato dal servizio sottostante era un valore Byte di "0" e non c'era alcun valore Enum corrispondente per il quale eseguire il cast.

Una volta accertato che i valori Enum erano tutti validi, lo strumento si accendeva come un albero di Natale.

In caso di dubbio, si supponga che i dati WCF non siano validi.

+0

C'era qualcosa nei file di tracciamento che puntava a questo o siamo bloccati con un errore generico di "pipe has ended" e dobbiamo scannerizzare tutto il codice in questione per trovare il potenziale problema di serializzazione? –

+3

Ho dovuto scansionare tutti i dati e verificarlo manualmente. Spero che tu abbia più fortuna con utili tracce! – BTownTKD

+0

"In caso di dubbi, supponi che i tuoi dati WCF non siano validi." - Ho salvato la mia giornata :) – Yaniv

1

Ho ricevuto questo errore quando l'operazione di servizio ha gettato e il canale era in realtà in errore. Nel tuo caso, hai già verificato che l'operazione di servizio è stata completata correttamente e che solo il ritorno è stato lanciato, ma in caso di dubbio, assicurati che l'operazione di servizio funzioni correttamente.

2

avuto lo stesso problema There was an error reading from the pipe: Unrecognized error 109 (0x6d).

  • Uno dei motivi era incoerente vincolante tra client e server <netNamedPipeBinding> <security mode="None"></security>... (nessuna comunicazione)
  • L'altro problema intermittente era legato time-out.

Entrambi avevano lo stesso messaggio di errore superiore.

Aumento del timeout nel problema arrestato dal binding del client e del server da riapparire.

tempo Binding che è stato fissato troppo basso:

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

traccia 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

questo è accaduto nel mio servizio WCF in cui il carico utile è tornato era troppo grande. Risolto il problema con l'aggiunta di questo in un servizioBehavior in app.config:

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

A volte questo errore causato dalla caratteristica polimorfica degli oggetti. ad esempio a seguito il metodo di servizio di elenco delle persone tornerà:

[OperationContract] 
List<Person> GetEmployee(); 

se abbiamo classe Supervisore ereditata dalla classe una persona, e il metodo di cui sopra cercare di tornare Supervisore oggetto, classe serializzatore WCF non può interpretare la risposta, in modo da questo errore verrà generato.
La soluzione per questo problema è di utilizzare "tipi noti" o "tipi noti di servizio". dobbiamo specificare che gli oggetti impliciti possono interagire usando il metodo o il servizio. Per il mio esempio, possiamo mettere attributo ServiceKnownType nel metodo o dichiarazione di servizio come codice seguente:

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

Questa eccezione significa che c'è un problema di serializzazione sul lato server.

Questo problema può essere risolto esaminando il file di traccia (svclog). Per attivare l'analisi sul uso la seguente configurazione:

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

Nel mio caso mi è stato serializzazione un valore che non era nel enum.

1

Avevo molte proprietà senza il set {}. Aggiungendo questo risolto il mio problema.

0

Stesso problema ma risolto grazie a Wojciech 's answer.

ho dovuto fare un po 'più a scavare per trovare dove mettere il tag <security>: ecco come l'inizio della sezione system.serviceModel sembra ora ...

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

ho avuto questo problema perché io stava usando un older tutorial e sta provando a configurare programmaticamente.

La parte che mancavo era quella di fornire l'endpoint dei metadati (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" 
); 
Problemi correlati