如何解决“ChannelDispatcher无法打开其IChannelListener”错误?

时间:2009-08-10 01:23:01

标签: c# wcf interprocess net.tcp

我正在尝试在Windows服务中托管的WCF与我的服务GUI之间进行通信。问题是当我尝试执行OperationContract方法时,我正在获取

  

“ChannelDispatcher at   '的net.tcp://本地主机:7771 /为MyService'   与合同'“IContract”'是   无法打开其IChannelListener。“

我的app.conf看起来像这样:

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

端口7771正在侦听(使用netstat检查),svcutil能够为我生成配置。

任何建议都将不胜感激。


来自异常的堆栈跟踪

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)

有一个内部执行(但不在Exeption.InnerExeption下但在Exeption.Detail.InnerExeption下 - ToString()方法没有显示)

  

URI'net.tcp:// localhost:7771 / MyService'已经存在注册。

但是我的服务只在app.config文件中指定了这个URI。在整个解决方案中,此URI在服务器中一次和客户端一次。

7 个答案:

答案 0 :(得分:7)

对于这种类型的异常,它是Inner异常,它具有诊断问题的有用信息。这是一个相当普遍的错误,可能是由一堆不同的东西造成的。

答案 1 :(得分:5)

我解决了它:D

以下是问题的解释:

第一个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
    }
}

正如您所看到的,服务合同是在托管服务的类中实现的。这导致整个错误的事情(也许typeof()运行一个构造函数,我不知道我对这个问题的建设性输入持开放态度。)

好的代码:

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

两个文件的服务合同:

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

答案 2 :(得分:4)

我知道你已经解决了这个问题,但是没有人指出它解决问题的原因,以及导致错误的原因。你的第一个代码的问题是你的程序(类程序)指定了对本身的类的开放调用&#34; class Program&#34;,换句话说,它是RECURSIVE。难怪它无法打开听众错误!这是一个很好的! : - )

答案 3 :(得分:1)

也许这个端口已经被你机器上的另一个程序使用,比如防病毒程序?或者它是Windows保留端口。你能尝试将端口设置为11111吗?

答案 4 :(得分:0)

我认为这部分配置会被忽略

<message clientCredentialType="UserName" />

设置

<security mode = "Transport">

答案 5 :(得分:0)

我遇到此异常的原因与OP相同,但我无法将我的服务实现移动到新类中。所以,我找到了另一个解决方案ServiceHost有第二个重载,它接受一个服务实例。因此,以下是应用于OP的'BAD'代码的更改:

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

答案 6 :(得分:0)

在再次呼叫服务之前,应该有一个host.Close()电话。因此使用try,catch和finally块。在第二次通话之前,最后关闭连接。