2009-08-10 4 views
9

J'essaie de communiquer entre WCF hébergé dans le service Windows et mon interface graphique de service. Le problème est quand je suis en train d'exécuter la méthode OperationContract Je reçoisComment faire pour résoudre "L'ChannelDispatcher est incapable d'ouvrir son erreur IChannelListener"?

« Le ChannelDispatcher à 'net.tcp: // localhost: 7771/MyService' avec contrat (s) « "IContract" ' impossible d'ouvrir son IChannelListener. "

Mon app.conf ressemble à ça:

<configuration> 
<system.serviceModel> 
    <bindings> 
     <netTcpBinding> 
      <binding name="netTcpBinding"> 
       <security> 
        <transport protectionLevel="EncryptAndSign" /> 
       </security> 
      </binding> 
     </netTcpBinding> 
    </bindings> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior name="MyServiceBehavior"> 
       <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:7772/MyService" /> 
       <serviceDebug includeExceptionDetailInFaults="true" /> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <services> 
     <service behaviorConfiguration="MyServiceBehavior" 
      name="MyService.Service"> 
      <endpoint address="net.tcp://localhost:7771/MyService" binding="netTcpBinding" 
       bindingConfiguration="netTcpBinding" name="netTcp" contract="MyService.IContract" /> 
     </service> 
    </services> 
</system.serviceModel> 

Port 7771 est à l'écoute (vérifié à l'aide netstat) et svcutil est capable de générer configs pour moi.

Toutes les suggestions seraient appréciées.


trace de la pile d'exception

Server stack trace: 
    at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter) 
    at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc) 
    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) 

Il y a une exeption intérieure (mais pas sous Exeption.InnerExeption mais sous Exeption.Detail.InnerExeption - méthode ToString() n » t montrer que)

Une inscription existe déjà pour URI 'net.tcp: // localhost: 7771/MyService'.

Mais mon service a spécifié cet URI uniquement dans le fichier app.config nulle part ailleurs. Dans toute la solution cet URI apparaît dans le serveur une fois et client une fois.

+0

Pouvez-vous nous donner une trace de pile complète en utilisant "theException.ToString()". Cela affichera toutes les exceptions internes. Avec ce genre d'exception, il y a parfois une autre cause profonde. –

Répondre

4

Je l'ai résolu: D

Voici le explanaition du problème:

le Code BAD:

namespace WCFServer 
{ 
    public class Program : IWCFService 
    { 
     private ServiceHost host; 

     static void Main(string[] args) 
     { 
      new Program(); 
     } 

     public Program() 
     { 
      host = new ServiceHost(typeof(Program)); 

      host.Open(); 

      Console.WriteLine("Server Started!"); 

      Console.ReadKey(); 
     } 

     #region IWCFService Members 

     public int CheckHealth(int id) 
     { 
      return (1); 
     } 

     #endregion 
    } 
} 

Comme vous pouvez le voir le contrat de service est mis en œuvre en classe d'accueil du service. Cela a causé toute la chose d'erreur (peut-être que typeof() exécute un constructeur, je ne sais pas je suis ouvert à une entrée constructive dans ce domaine).

Le code BON:

namespace WCFServer 
{ 
    public class Program 
    { 
     private ServiceHost host; 

     static void Main(string[] args) 
     { 
      new Program(); 
     } 

     public Program() 
     { 
      host = new ServiceHost(typeof(WCF)); 

      host.Open(); 

      Console.WriteLine("Server Started!"); 

      Console.ReadKey(); 
     } 
    } 

    public class WCF : IWCFService 
    { 

     #region IWCFService Members 

     public int CheckHealth(int id) 
     { 
      return (1); 
     } 

     #endregion 
    } 
} 

contrat de service pour les deux fichiers:

[ServiceContract] 
public interface IWCFService 
{ 
    [OperationContract] 
    int CheckHealth(int id); 
} 

App.config

<configuration> 
<system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior name="WCFBehavior" /> 
     </serviceBehaviors> 
    </behaviors> 
    <bindings> 
     <netTcpBinding> 
      <binding name="tcpBinding"> 
       <security> 
        <transport> 
         <extendedProtectionPolicy policyEnforcement="Never" /> 
        </transport> 
       </security> 
      </binding> 
     </netTcpBinding> 
    </bindings> 
    <services> 
     <service name="WCFServer.WCF"> 
      <endpoint address="net.tcp://localhost:1111/TcpIHostMonitor" binding="netTcpBinding" 
       bindingConfiguration="tcpBinding" name="netTcpEndpoint" contract="WCFServer.IWCFService" /> 
     </service> 
    </services> 
</system.serviceModel> 

1

peut-être le port est déjà utilisé par un autre programme sur votre machine, comme un programme antivirus? Ou c'est un port réservé Windows. Pourriez-vous essayer de configurer le port à quelque chose comme 11111?

+0

Malheureusement, ce n'est pas le cas. J'ai essayé différents ports (7771, 7772, 7773). Les ports disparaissent de la sortie netstat après avoir éteint mon service, donc probablement rien d'autre ne les écoute: / – kyrisu

7

Avec ce type d'exception, il est l'exception interne qui a l'information qui est utile pour diagnostiquer le problème. C'est une erreur plutôt générique qui pourrait être causée par un tas de choses différentes.

0

Je pense que cette partie de la configuration est ignorée

<message clientCredentialType="UserName" /> 

lorsque vous définissez

<security mode = "Transport"> 
0

j'ai rencontré cette exception pour la même raison que l'OP mais je ne pouvais pas bouger la mise en œuvre de mon service dans une nouvelle classe. Donc, j'ai trouvé une autre solution. ServiceHost a une deuxième surcharge qui prend une instance d'un service. Ainsi, voici les modifications appliquées au code « MAUVAIS » de l'OP:

namespace WCFServer 
{ 
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] // required 
    public class Program : IWCFService 
    { 
     private ServiceHost host; 

     static void Main(string[] args) 
     { 
      new Program(); 
     } 

     public Program() 
     { 
      host = new ServiceHost(this); // changed 
      host.Open(); 

      Console.WriteLine("Server Started!"); 
      Console.ReadKey(); 
     } 

     #region IWCFService Members 

     public int CheckHealth(int id) 
     { 
      return (1); 
     } 

     #endregion 
    } 
} 
1

Je sais que vous avez déjà résolu le problème, mais personne ne fait remarquer pourquoi il a résolu le problème, et ce qui a causé l'erreur. Le problème avec votre premier code était que votre programme (classe Program) spécifiait un appel ouvert à la classe qui était elle-même "class Program", en d'autres termes, c'est RECURSIVE. Pas étonnant qu'il donnait l'incapable d'ouvrir l'erreur d'écoute! C'était un bon! :-)

Questions connexes