WCF NamedPipe CommunicationException – “Le tube a été terminé. (109, 0x6d). ”

J’écris un service Windows avec “l’outil d’état”. Le service héberge un sharepoint terminaison de tuyau nommé WCF pour la communication interprocessus. Grâce au canal nommé, l’outil d’état peut périodiquement interroger le service pour connaître le dernier “état”.

entrez la description de l'image ici

Sur ma machine de développement, j’ai plusieurs adresses IP. l’un d’eux est un réseau “local” avec une adresse 192.168.1.XX. L’autre est le réseau “d’entreprise”, avec une adresse 10.0.X.XX. Le service Windows collecte le trafic de multidiffusion UDP sur une seule adresse IP.

Jusqu’à présent, le service Windows fonctionnait correctement tant qu’il utilisait l’adresse “192.168.1.XX,”. Il enregistre systématiquement le statut correctement au client.

Dès que je suis passé à l’autre adresse IP “entreprise” (10.0.X.XX) et que j’ai redémarré le service, je reçois en permanence des “CommunicationsExceptions” lors de l’extraction du statut:

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

À présent, je ne pense pas que l’adresse IP “revendiquée” du client UDP devrait avoir quelque chose à voir avec les fonctionnalités de l’interface Named-Pipe; ce sont des pièces complètement séparées de l’application!

Voici les sections pertinentes de la configuration WCF:

 //On the Client app: ssortingng myNamedPipe = "net.pipe://127.0.0.1/MyNamedPipe"; ChannelFactory proxyFactory = new ChannelFactory( new NetNamedPipeBinding(), new EndpointAddress(myNamedPipe)); //On the Windows Service: ssortingng 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(); 

Je ne pense pas qu’il s’agisse d’un problème d’permissions – j’utilise le client avec des privilèges d’administrateur – mais il y a peut-être une raison spécifique à un domaine qui a provoqué cette défaillance?

Il s’est avéré que l’adresse IP était un véritable fil rouge.

La vraie raison de l’exception était que des valeurs Enum non valides étaient renvoyées par le service WCF.

Mon enum a été défini ainsi:

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

Ça a l’air bien en surface.

Mais l’état brut indiqué par le service sous-jacent était une valeur d’octet de “0” et aucune valeur Enum correspondante ne pouvait être exprimée.

Une fois que je me suis assuré que les valeurs Enum étaient toutes valides, l’outil s’est éclairé comme un arbre de Noël.

En cas de doute, supposez que vos données WCF sont invalides.

Avait le même problème There was an error reading from the pipe: Unrecognized error 109 (0x6d).

  • Une des raisons était une liaison incohérente entre le client et le serveur ... (aucune communication)
  • L’autre problème intermittent était lié au délai d’attente.

Les deux avaient le même message d’erreur en haut.

L’augmentation du délai d’expiration dans la liaison serveur et client a empêché la réapparition du problème.

Délai d’attente de liaison défini trop bas:

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

Trace de 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(Ssortingng action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(Ssortingng 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) 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(Ssortingng action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(Ssortingng 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)

Parfois, cette erreur est causée par une caractéristique polymorphe des objects. Par exemple, la méthode suivante du service retournera la liste des personnes:

 [OperationContract] List GetEmployee(); 

Si nous avons la classe Supervisor héritée de la classe Person et que la méthode ci-dessus tente de renvoyer Supervisor Object, la classe de sérialiseur WCF ne peut pas interpréter la réponse. Cette erreur sera donc générée .
La solution à ce problème consiste à utiliser des “types connus” ou des “types connus du service” . nous devons spécifier que les objects implicites peuvent interagir à l’aide de la méthode ou du service. Pour mon exemple, nous pouvons mettre l’atsortingbut ServiceKnownType dans la déclaration de méthode ou de service comme code suivant:

 [OperationContract] [ServiceKnownType(typeof(Supervisor))] List GetEmployee(); 

Cette exception signifie qu’il existe un problème de sérialisation côté serveur.

Ce problème peut être résolu en consultant le fichier de trace (svclog). Pour activer le traçage, utilisez la configuration suivante:

                  

Dans mon cas, je sérialisais une valeur qui n’était pas dans l’énum.

Cela s’est produit dans mon service WCF lorsque la charge utile renvoyée était trop importante. Corrigé en ajoutant ceci à un serviceBehavior dans app.config:

  

J’ai eu cette erreur lorsque l’opération de service a jeté et le canal a été réellement mis en défaut. Dans votre cas, vous avez déjà vérifié que l’opération de service en tant que telle s’est correctement terminée et que seul le retour a été effectué, mais en cas de doute, assurez-vous que l’opération de service fonctionne correctement.

J’avais beaucoup de propriétés sans ensemble {}. Ajouter ceci a résolu mon problème.

Même problème mais résolu grâce à la réponse de Wojciech .

J’ai dû creuser un peu plus pour trouver où placer la . Voici donc à quoi ressemble le début de la section system.serviceModel …

         .... 

J’ai eu ce problème parce que j’utilisais un tutoriel plus ancien et que j’essayais de configurer par programme.

La partie qui me manquait était de fournir le sharepoint terminaison des métadonnées ( merci, cet article! ).

 ServiceMetadataBehavior serviceMetadataBehavior = host.Description.Behaviors.Find(); if (serviceMetadataBehavior == null) { serviceMetadataBehavior = new ServiceMetadataBehavior(); host.Description.Behaviors.Add(serviceMetadataBehavior); } host.AddServiceEndpoint( typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexNamedPipeBinding(), "net.pipe://localhost/PipeReverse/mex" );