2009-08-10 29 views
9

Estoy tratando de comunicarme entre WCF alojado en el Servicio de Windows y mi GUI de servicio. El problema es cuando estoy tratando de ejecutar OperationContract método que estoy recibiendo¿Cómo resolver "The ChannelDispatcher no puede abrir su IChannelListener" error?

"El ChannelDispatcher en 'net.tcp: // localhost: 7771/MyService' con un contrato (s) ' "IContract" 'es incapaz de abrir su IChannelListener'.

Mi app.conf parece que:

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

puerto 7771 está escuchando (comprobado mediante netstat) y svcutil es capaz de generar configuraciones para mí.

Cualquier sugerencia sería apreciada. rastro


Pila de excepción

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) 

Hay una excepcion interior (pero no bajo Exeption.InnerExeption pero bajo Exeption.Detail.InnerExeption - método ToString() doesn' t show that)

Un registro ya existe para URI 'net.tcp: // localhost: 7771/MyService'.

Pero mi servicio ha especificado este URI solo en el archivo app.config en ningún otro lugar. En toda la solución, este URI aparece en el servidor una vez y el cliente una vez.

+0

¿Puede darnos un rastro de pila completo usando "theException.ToString()". Esto mostrará todas las excepciones internas. Con este tipo de excepción a veces hay otra causa raíz. –

Respuesta

4

Lo resuelto: D

Aquí está la explanaition del problema:

primer código MALO:

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

Como se puede ver el contrato de servicio se implementa en la clase que aloja el servicio. Esto causó todo el error (tal vez typeof() ejecuta un constructor, no sé, estoy abierto a la entrada constructiva en este asunto).

el Código de Buen:

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

contrato de servicio para ambos archivos:

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

aplicación.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

quizás el puerto ya esté siendo utilizado por otro programa en su máquina, como un programa antivirus? O es un puerto reservado de Windows. ¿Podría intentar configurar el puerto a algo como 11111?

+0

desafortunadamente no lo es. He probado diferentes puertos (7771, 7772, 7773). Los puertos desaparecen de la salida netstat después de apagar mi servicio, por lo que probablemente no haya nada más escuchando en ellos: / – kyrisu

7

Con este tipo de excepción es la excepción interna que tiene la información que es útil para diagnosticar el problema. Este es un error bastante genérico que podría ser causado por un montón de cosas diferentes.

0

creo que esta parte de la configuración se ignora

<message clientCredentialType="UserName" /> 

cuando se establece

<security mode = "Transport"> 
0

me encontré con esta excepción por la misma razón que la OP pero no podía mover la aplicación de mi servicio en una nueva clase. Entonces, encontré otra solución. ServiceHost tiene una segunda sobrecarga que toma una instancia de un servicio. Por lo tanto, aquí están los cambios aplicados al código 'malo' de la 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

Sé que ya resuelto el problema, pero nadie se señalaron por lo que resolvió el problema, y ​​lo que ha provocado el error. El problema con su primer código era que su programa (Programa de clase) especificaba una llamada abierta a la clase que era en sí misma "Programa de clase", en otras palabras, es RECURSIVO. ¡No es de extrañar que le estuviera dando al incapaz de abrir el error del oyente! ¡Este fue uno bueno! :-)

Cuestiones relacionadas