13

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

“'net.tcp://localhost:7771/MyService' 的 ChannelDispatcher 与合同 ''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 出现在服务器一次和客户端一次。

4

7 回答 7

9

对于这种类型的异常,内部异常具有对诊断问题有用的信息。这是一个相当普遍的错误,可能是由一堆不同的事情引起的。

于 2010-04-08T03:51:25.633 回答
5

我解决了:D

这是问题的解释:

第一个坏代码:

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

应用程序配置

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

于 2009-08-10T11:46:38.103 回答
4

我知道您已经解决了问题,但没有人指出它解决问题的原因以及导致错误的原因。您的第一个代码的问题是您的程序(程序类)指定了对本身是“类程序”的类的公开调用,换句话说,它是递归的。难怪它给出了无法打开侦听器的错误!这是一个很好的!:-)

于 2016-09-12T05:57:05.153 回答
1

也许该端口已被您机器上的另一个程序(如防病毒程序)使用?或者它是一个 Windows 保留端口。您可以尝试将端口设置为 11111 之类的东西吗?

于 2009-08-10T10:02:23.430 回答
0

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

<message clientCredentialType="UserName" />

当你设置

<security mode = "Transport">
于 2010-11-11T03:09:22.353 回答
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
    }
}
于 2014-09-04T19:51:48.720 回答
0

host.Close()在再次调用服务之前应该有一个调用。因此使用 try、catch 和 finally 块。在进行第二次调用之前,最终关闭连接。

于 2018-04-04T00:22:20.297 回答