2009-08-10 5 views
9

Я пытаюсь установить связь между WCF, размещенным в службе Windows, и моим графическим интерфейсом службы. Проблема заключается в том, когда я пытаюсь выполнить OperationContract метод я получаюКак решить «Ошибка ChannelDispatcher не удается открыть его IChannelListener»?

«The ChannelDispatcher в 'net.tcp: // локальный: 7771/MyService' с контрактом (s)«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 (но не под Exeption.InnerExeption но под Exeption.Detail.InnerExeption - метод ToString() Безразлично» t показать, что)

Регистрация уже существует для URI 'net.tcp: // localhost: 7771/MyService'.

Но моя служба указала этот URI только в файле app.config больше нигде. Во всем решении этот URI появляется на сервере один раз и клиент один раз.

+0

Можете ли вы дать нам полную трассировку стека, используя «theException.ToString()». Это отобразит все внутренние исключения. При таком исключении иногда возникает и другая причина. –

ответ

4

Я решил его: D

Вот explanaition проблемы:

Первый 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.конфиг

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

1

Возможно, порт уже используется другой программой на вашем компьютере, как антивирусная программа? Или это зарезервированный порт Windows. Не могли бы вы попытаться установить порт на что-то вроде 11111?

+0

, к сожалению, это не так. Я пробовал разные порты (7771, 7772, 7773). Порты исчезают из вывода netstat после отключения моего сервиса, поэтому, вероятно, ничто не слушает их: / – kyrisu

7

С этим типом исключения это внутреннее исключение, которое имеет информацию, которая полезна для диагностики проблемы. Это довольно общая ошибка, которая может быть вызвана множеством разных вещей.

0

Я думаю, что эта часть конфигурации игнорируется

<message clientCredentialType="UserName" /> 

при установке

<security mode = "Transport"> 
0

Я столкнулся с этим исключение по той же причине, что и ОП, но я не мог двигаться реализации моего сервиса в новый класс. Итак, я нашел другое решение. ServiceHost имеет вторую перегрузку, которая принимает экземпляр службы. Таким образом, здесь изменения, внесенные в «BAD» кода OP в:

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

Я знаю, что вы уже решили эту проблему, но никто не указал, почему он решил проблему, и что вызвало ошибку. Проблема с вашим первым кодом заключалась в том, что ваша программа (Class Program) указала на открытый вызов класса, который сам был «классной программой», другими словами, это RECURSIVE. Неудивительно, что это давало возможность не открывать ошибку слушателя! Это было хорошо! :-)