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

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-01 03:24:38

With this type of exception it's the Inner exception that has the information that is useful to diagnose the problem. This is a rather generic error that could be caused by a bunch of different things.

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>

I know you already solved the problem, but nobody pointed out why it solved the problem, and what caused the error. The issue w/ your first code was that your program (class Program) specified an open call to the class that was itself "class Program", in other words, it's RECURSIVE. No wonder it was giving the unable to open the listener error! This was a good one! :-)

maybe the port is already used by another program on your machine, like an antivirus program? Or it's a Windows reserved port. Could you try setting the port to something like 11111?

I think this part of the configuration is ignored

<message clientCredentialType="UserName" />

when you set

<security mode = "Transport">

I encountered this exception for the same reason as the OP but I couldn't move my service's implementation into a new class. So, I found another solution. ServiceHost has a second overload that takes an instance of a service. Thus, here are the changes applied to the OP's 'BAD' code:

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

There should be a host.Close() call before calling the service again. Therefore use try, catch and finally block. Close the connection in finally before making second call.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!