2016-09-09 17 views
1

Я пытаюсь создать обратный вызов в службе WCF. Сервис пока использовал basicHttpBinding, поэтому я хочу добавить еще одну конечную точку для netTcpBinding. Служба уже размещена в IIS. Сначала он размещался в IIS 6, но затем я установил IIS 7.WCF netTcpBinding проблема: контракт требует дуплекса, но привязка «BasicHttpBinding» не поддерживает его или неправильно настроена для его поддержки.

Таким образом, я получаю следующее сообщение об ошибке:

The requested service, 'net.tcp://localhost:1801/MyServiceName.svc/NetTcpExampleAddress' could not be activated. See the server's diagnostic trace logs for more information.

Увидев журнал, это сообщение:

enter image description here

Таким образом, основная ошибка:

Contract requires Duplex, but Binding 'BasicHttpBinding' doesn't support it or isn't configured properly to support it.

Вот мой конфи г файлы:

Мой Web.config для сервера:

<system.serviceModel> 
    <bindings> 
     <netTcpBinding> 
     <binding name="demoServiceNetTcpBinding"> 
      <security mode="None"/> 
     </binding> 
     </netTcpBinding> 
     <basicHttpBinding> 
     <binding name="demoServiceHttpBinding" receiveTimeout="00:05:00" sendTimeout="00:05:00" maxReceivedMessageSize="2147483647"> 
      <security mode="None"/> 
     </binding>   
     </basicHttpBinding> 
    </bindings> 
    <services> 
     <service name="MyServerName.MyServiceName"> 
     <host> 
      <baseAddresses> 
      <add baseAddress="net.tcp://localhost:1801/MyServiceName.svc/"/> 
      <add baseAddress="http://localhost:1800/MyServiceName.svc/"/> 
      </baseAddresses> 
     </host> 
    <endpoint 
     address="NetTcpExampleAddress" 
     binding="netTcpBinding" 
     bindingConfiguration="demoServiceNetTcpBinding" 
     contract="MyServerName.SharedContract.IMyServiceName"/> 
    <endpoint 
     address="BasicHttpExampleAddress" 
     binding="basicHttpBinding" 
     bindingConfiguration="demoServiceHttpBinding" 
     contract="MyServerName.SharedContract.IMyServiceName"/> 
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <serviceDebug includeExceptionDetailInFaults="true"/> 
      <serviceMetadata httpGetEnabled="true"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 

Мои App.config для клиента:

<system.serviceModel> 
    <bindings> 
     <netTcpBinding> 
     <binding name="demoServiceNetTcpBinding"> 
      <security mode="None"/> 
     </binding> 
     </netTcpBinding> 
     <basicHttpBinding> 
     <binding name="demoServiceHttpBinding" receiveTimeout="00:05:00" sendTimeout="00:05:00" maxReceivedMessageSize="2147483647"> 
      <security mode="None"/> 
     </binding>   
     </basicHttpBinding> 
    </bindings> 
    <client> 
     <endpoint name="NetTcpExampleName" 
      address="net.tcp://localhost:1801/DicomQueryService.svc/NetTcpExampleAddress" 
      bindingConfiguration ="demoServiceNetTcpBinding" 
      contract="MyServerName.SharedContract.IMyServiceName" 
      binding="netTcpBinding" /> 
     <endpoint name="BasicHttpExampleName" 
      address="http://localhost:1800/MyServiceName.svc/BasicHttpExampleAddress" 
      bindingConfiguration ="demoServiceHttpBinding" 
      contract="MyServerName.SharedContract.IMyServiceName" 
      binding="basicHttpBinding" /> 
    </client> 
    </system.serviceModel> 

Настройки в моем IIS:

enter image description here

enter image description here

Если есть какие-либо другие фрагменты кода, которые вам нужны, сообщите мне, и я обновлю вопрос.

EDIT 1:

Вот более подробная информация из кода, о том, как я звоню в службу от клиента (на стороне клиента):

public class MyCommandClass : IMyServiceCallback 
{ 
    public MyCommandClass() 
    { 
     var ctx = new InstanceContext(new MyCommandClass()); 
     DuplexChannelFactory<MyServerName.SharedContract.IMyServiceName> channel = new DuplexChannelFactory<MyServerName.SharedContract.IMyServiceName>(ctx, "NetTcpExampleName"); 
     MyServerName.SharedContract.IMyServiceName clientProxy = channel.CreateChannel(); 
     clientProxy.MyFunction(); //debug point is comming here and then it throws the error 
     clientProxy.ProcessReport(); 
     (clientProxy as IClientChannel).Close(); 
     channel.Close(); 
    } 

    public void Progress(int percentageCompleted) 
    { 
     Console.WriteLine(percentageCompleted.ToString() + " % completed"); 
    } 
} 

где интерфейсы (на сервере сторона) определяется как:

[ServiceContract(CallbackContract = typeof(IMyServiceCallback))] 
public interface IMyServiceName 
{ 
    [OperationContract] 
    void MyFunction(); 

    [OperationContract(IsOneWay = true)] 
    void ProcessReport(); 
} 

public interface IMyServiceCallback 
{ 
    [OperationContract(IsOneWay = true)] 
    void Progress(int percentageCompleted);  
} 

и обслуживание (на стороне сервера) определяются следующим образом:

public class MyServiceName: IMyServiceName 
{ 
    public void MyFunction() 
    { 
     //do something 
    } 

    public void ProcessReport() 
    { 
     //trigger the callback method 
     for (int i = 1; i <= 100; i++) 
     { 
      Thread.Sleep(100); 
      OperationContext.Current.GetCallbackChannel<IMyServiceCallback>().Progress(i); 
     } 
    } 
} 

Мои методы - это всего лишь демонстрация. После исправления ошибки, связанной с этим вопросом, я начну с разработки методов.

+0

Был ли demoQueryServiceHttpBinding предполагаемым demoServiceHttpBinding? – jcmcbeth

+0

Не могли бы вы опубликовать, как вы звоните в службу от клиента? – jcmcbeth

+0

@jcmcbeth Я переименовал demoQueryServiceHttpBinding в demoServiceHttpBinding. Это была просто синтаксическая ошибка, когда я писал вопрос. Основной вопрос по-прежнему остается. Также я уточнил вопрос с большим количеством кода (в редакторе 1), связанным с способом вызова службы. – delux

ответ

1

Для вашего контракта на обслуживание требуется дуплексное соединение (у вас есть атрибут ServiceCallback). Поэтому все конечные точки, предоставляемые этой службой, должны поддерживать дуплексное соединение. Net.tcp действительно поддерживает его, но basicHttp нет, поэтому теперь вы не можете использовать basicHttp с вашим сервисом.

+0

Я сделал некоторые изменения в Web.config: я удалил конечную точку «BasicHttpExampleAddress», и это решило мою проблему. Также я переименовал конечную точку «mex» в «mextcp». Так что это решило мою проблему, но что, если я хочу иметь «basicHttpBining», а также здесь. Возможно ли иметь разные конечные точки: «basicHttpBining» (без обратного вызова) и «netTcpBinding» (с обратным вызовом) в одно и то же время? – delux

+1

Вам нужно будет использовать два разных контракта. Поскольку контракт определяет, какие операции могут выполнять клиенты. И если контракт говорит, что он имеет обратный вызов, тогда клиент должен иметь возможность использовать обратный вызов независимо от того, как он подключается к службе. Если у вашей службы также есть другой способ работы (т. Е. Без обратных вызовов), тогда определите еще один контракт, который не использует 'ServiceCallbackAttribute' и реализует другой класс обслуживания. Затем вы сможете открыть его через конечную точку basicHttp. Ваши две службы могут использовать один и тот же «бэкэнд» внутри для операций. –