C# 如何解决“ChannelDispatcher 无法打开其 IChannelListener”错误?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1252791/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to solve "The ChannelDispatcher is unable to open its IChannelListener" error?
提问by kyrisu
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
我正在尝试在 Windows 服务中托管的 WCF 和我的服务 GUI 之间进行通信。问题是当我尝试执行我得到的 OperationContract 方法时
"The ChannelDispatcher at 'net.tcp://localhost:7771/MyService' with contract(s) '"IContract"' is unable to open its IChannelListener."
“'net.tcp://localhost:7771/MyService' 上的 ChannelDispatcher 与合约 ''IContract'' 无法打开其 IChannelListener。”
My app.conf looks like that:
我的 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>
Port 7771 is listening (checked using netstat) and svcutil is able to generate configs for me.
端口 7771 正在侦听(使用 netstat 检查)并且 svcutil 能够为我生成配置。
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)
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)
有一个内部例外(但不在 Exeption.InnerExeption 下,但在 Exeption.Detail.InnerExeption 下 - ToString() 方法没有显示)
A registration already exists for URI 'net.tcp://localhost:7771/MyService'.
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.
但是我的服务只在 app.config 文件中指定了这个 URI,其他地方都没有。在整个解决方案中,此 URI 在服务器中出现一次,在客户端中出现一次。
采纳答案by kyrisu
I solved it :D
我解决了: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).
如您所见,服务契约是在托管服务的类中实现的。这导致了整个错误的事情(也许 typeof() 运行一个构造函数,我不知道我对这件事的建设性意见持开放态度)。
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>
回答by Colin
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?
也许该端口已被您机器上的另一个程序使用,例如防病毒程序?或者它是 Windows 保留端口。您可以尝试将端口设置为 11111 之类的内容吗?
回答by Nate Zaugg
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.
对于这种类型的异常,内部异常具有可用于诊断问题的信息。这是一个相当普遍的错误,可能由一系列不同的事情引起。
回答by Hymanie Weng
I think this part of the configuration is ignored
我认为这部分配置被忽略了
<message clientCredentialType="UserName" />
when you set
当你设置
<security mode = "Transport">
回答by Pakman
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:
由于与 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
}
}
回答by eric frazer
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! :-)
我知道你已经解决了这个问题,但是没有人指出它为什么解决了这个问题,以及是什么导致了错误。您的第一个代码的问题是您的程序(类 Program)指定了对本身是“类 Program”的类的开放调用,换句话说,它是递归的。难怪它给出了无法打开侦听器的错误!这是一个很好的!:-)
回答by 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.
在host.Close()
再次调用服务之前应该有一个调用。因此使用 try、catch 和 finally 块。在进行第二次调用之前,在 finally 中关闭连接。