Search code examples
c#wcfinterprocessnet.tcp

How to solve "The ChannelDispatcher is unable to open its IChannelListener" error?


I'm trying to communicate between WCF hosted in Windows Service and my service GUI. The problem is when I'm trying to execute OperationContract method I'm getting

"The ChannelDispatcher at 'net.tcp://localhost:7771/MyService' with contract(s) '"IContract"' is unable to open its IChannelListener."

My app.conf looks like that:

<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 is listening (checked using netstat) and svcutil is able to generate configs for me.

Any suggestions would be appreciated.


Stack trace from 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)

There's one inner exeption (but not under Exeption.InnerExeption but under Exeption.Detail.InnerExeption - ToString() method doesn't show that)

A registration already exists for URI 'net.tcp://localhost:7771/MyService'.

But my service have specified this URI only in app.config file nowhere else. In entire solution this URI apears in server once and client once.


Solution

  • I solved it :D

    Here's the explanaition of the problem:

    First BAD code:

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

    As you can see the service contract is implemented in class hosting the service. This caused the whole error thing (maybe typeof() runs a constructor, i don't know I'm open to constructive input in this matter).

    The GOOD code:

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

    Service Contract for both files:

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