2013-09-30 5 views
3

Я использую TCP привязки в WCF службе и мой обратный вызов на стороне клиента в не получает called.This моего кодане называется

Сервис

public interface IMyContractCallback 
{ 
    [OperationContract(IsOneWay = true)] 
    void OnCallback(); 
} 

[ServiceContract(CallbackContract = typeof (IMyContractCallback),SessionMode = 
SessionMode.Required)] 
public interface IService1 
{ 

    [OperationContract(IsOneWay = true)] 
    void DoSomething();  


     [OperationContract] 
    int GetCount(); 
} 

public class Service1 : IService1 
{ 

    private int count=0; 
    public int GetCount() 
    { 
     return count; 
    } 

    public void DoSomething() 
    { 
     count++; 
     Console.WriteLine("increased count"); 
     IMyContractCallback callback = 
       OperationContext.Current.GetCallbackChannel<IMyContractCallback>(); 

      if ((callback as IChannel).State == CommunicationState.Opened) 
      { 
       callback.OnCallback(); 
      } 

    }  
} 

и мой клиент

public class App1 
{ 


    private MyServiceCallback callback; 
    private InstanceContext context; 
    private Service1Client proxy;  

    public App1() 
    { 
     callback=new MyServiceCallback(); 


     context = new InstanceContext(callback); 
     var factory = new DuplexChannelFactory<IService1>(callback, "EndPointTCP"); 
     IService1 proxy = factory.CreateChannel(); 

     callback.proxy = proxy; 

     proxy.DoSomething(); 


    } 
} 

public class MyServiceCallback : IService1Callback 
{ 

    public IService1 proxy 
    { 
     get; 
     set; 
    } 
    public void OnCallback() 
    { 

     Console.WriteLine("Callback thread = " + Thread.CurrentThread.ManagedThreadId); 
     Console.WriteLine(proxy.GetCount()); 

    } 
} 

сталкивается две проблем:

1их не получает обратный вызов из DoSomething с выше Menti код. 2.Ела я объявляю DoSomething, как TwoWay, я получить обратный вызов, но он бросает исключение «Сервер не обеспечивает значимый ответ»

Моего клиент конфигурация

<?xml version="1.0" encoding="utf-8" ?> 
    <configuration> 
<system.serviceModel> 
    <bindings> 
     <netTcpBinding> 
      <binding name="EndPointTCP" closeTimeout="00:10:00" openTimeout="00:10:00" 
       receiveTimeout="00:10:00" sendTimeout="00:10:00" 
       transactionFlow="false" 
       transferMode="Buffered" transactionProtocol="OleTransactions" 
       hostNameComparisonMode="StrongWildcard" listenBacklog="10" 
       maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10" 
       maxReceivedMessageSize="65536"> 
       <readerQuotas maxDepth="32" maxStringContentLength="8192" 
       maxArrayLength="16384" 
        maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
       <reliableSession ordered="true" inactivityTimeout="00:20:00" 
        enabled="true" /> 
       <security mode="Transport"> 
        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> 
        <message clientCredentialType="Windows" /> 
       </security> 
      </binding> 
     </netTcpBinding> 
     <wsDualHttpBinding> 
      <binding name="EndPointHTTP" closeTimeout="00:01:00" openTimeout="00:01:00" 
       receiveTimeout="00:10:00" sendTimeout="00:01:00" 
       bypassProxyOnLocal="false" 
       transactionFlow="false" hostNameComparisonMode="StrongWildcard" 
       maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
       messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"> 
       <readerQuotas maxDepth="32" maxStringContentLength="8192" 
        maxArrayLength="16384" 
        maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
       <reliableSession ordered="true" inactivityTimeout="00:10:00" /> 
       <security mode="Message"> 
        <message clientCredentialType="Windows" 
          negotiateServiceCredential="true" 
         algorithmSuite="Default" /> 
       </security> 
      </binding> 
     </wsDualHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="masked" 
      binding="wsDualHttpBinding" bindingConfiguration="EndPointHTTP" 
      contract="ServiceReference1.IService1" name="EndPointHTTP"> 
      <identity> 
       <servicePrincipalName value="masked" /> 
      </identity> 
     </endpoint> 
     <endpoint address="masked" 
      binding="netTcpBinding" bindingConfiguration="EndPointTCP" 
      contract="ServiceReference1.IService1" name="EndPointTCP"> 
      <identity> 
       <servicePrincipalName value="masked" /> 
      </identity> 
     </endpoint> 
    </client> 
</system.serviceModel> 
    </configuration> 

моей служба конфигурация

<?xml version="1.0" encoding="UTF-8"?> 
<configuration> 


<system.web> 
<compilation debug="true" targetFramework="4.0"/> 
<httpRuntime maxRequestLength="102400" /> 

</system.web> 

<system.diagnostics> 
<sources> 
    <source name="System.ServiceModel" 
      switchValue="Information, ActivityTracing" 
      propagateActivity="true"> 
    <listeners> 
     <add name="traceListener" 
      type="System.Diagnostics.XmlWriterTraceListener" 
      initializeData= "d:\log\Traces.svclog" /> 
    </listeners> 
    </source> 
</sources> 
</system.diagnostics> 

<system.serviceModel> 
<bindings> 
    <netTcpBinding> 
    <binding name="TcpBinding" maxBufferPoolSize="2147483647" 
     maxBufferSize="2147483647" 
     maxReceivedMessageSize="2147483647" portSharingEnabled="true" > 
     <readerQuotas maxDepth="32" maxStringContentLength="2147483647" 
     maxArrayLength="2147483647" 
     maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> 
     <security mode="Transport"/> 
     <reliableSession enabled="true" /> 
    </binding> 
    </netTcpBinding> 
</bindings> 
<services> 
    <service behaviorConfiguration="WcfService2.MyServiceBehaviour" 
    name="WcfService2.Service1"> 
    <endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="" 
     name="EndPointHTTP" contract="WcfService2.IService1" /> 
    <endpoint address="" binding="netTcpBinding" bindingConfiguration="TcpBinding" 
     name="EndPointTCP" contract="WcfService2.IService1" isSystemEndpoint="false" /> 
    <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="" 
     name="mexpoint" contract="IMetadataExchange" /> 
    </service> 
</services> 
<behaviors> 
    <serviceBehaviors> 
    <behavior name="WcfService2.MyServiceBehaviour"> 
     <serviceMetadata httpGetEnabled="false" /> 
     <serviceThrottling maxConcurrentSessions="10000"/> 
     <serviceDebug includeExceptionDetailInFaults="true" /> 
     <dataContractSerializer maxItemsInObjectGraph="2147483647" /> 
    </behavior> 
    </serviceBehaviors> 
    </behaviors> 
</system.serviceModel> 
<system.webServer> 
    <modules runAllManagedModulesForAllRequests="true" /> 
    <directoryBrowse enabled="true" showFlags="Date, Time, Size, Extension, LongDate" /> 
    </system.webServer> 

    </configuration> 
+0

I подумайте, что название вашего вопроса вводит в заблуждение. Последний абзац указывает, что вы получаете обратный вызов; Реальная проблема заключается в том, почему 'GetCount()' не работает. Согласитесь? – Jay

+0

В качестве первого шага по устранению неполадок, я попытаюсь изменить 'SessionMode.Required' на' SessionMode.Allowed'. Я также переместил бы 'DeRegister' в обработчик обратного вызова; это позволит вам вернуть 'IsOneWay' обратно в' DoSomething() '. – Jay

+0

вы могли бы поделиться своим сервисом и сервисом конфигурации файла конфигурации клиента. –

ответ

3

Проблема в том, что вы снова вызываете службу из обратного вызова. Если вы оставите это, нет никакой ошибки в отношении «никакого значимого ответа».

Это должно помочь установить атрибут ConcurrencyMode к вашим услугам и обратного вызова класса:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class Service1 : IService1 
... 

и

[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class MyServiceCallback : IService1Callback 
... 

Вы должны установить "IsOneWay = ложь" в OperationContract, конечно.

+0

Это не решение, даже если я еще не позвоню снова из обратного вызова. Я все равно получаю «бессмысленную ошибку ответа», а также не мог бы вы подробно остановиться на «Вы должны установить« IsOneWay = false »в OperationContract, конечно». Я уверен, что у нас также могут быть обратные вызовы из односторонних операций, но как-то не работает в моем случае. – TRS

+0

«Проблема в том, что вы снова вызываете службу из обратного вызова» - это хорошая точка –

+0

Ну, я мог бы воспроизвести описанное вами, пока не установлю ConcurrencyMode или не удалю вызов GetCount. OTOH, у меня нет вашего оригинального проекта. Может ли он быть загружен где-нибудь? Обратные вызовы не работают с «IsOneWay = true». Возможно, однако, что это подразумевается, как только используются обратные вызовы. – JeffRSon

1

Он должен работать, используя IsOneWay = верно ..

Ниже приведен пример

---- Service Code

[ServiceContract(CallbackContract = typeof(IServerFinishedProcessingCallback), SessionMode = SessionMode.Required)] 
public interface IDualMathService 
{ 
    [OperationContract(IsOneWay=true)] 
    void ProcessAdd(double num1, double num2); 

    [OperationContract(IsOneWay = true)] 
    void ProcessSubtract(double num1, double num2); 

    [OperationContract(IsOneWay=true)] 
    void ProcessMultiply(double num1, double num2); 

    [OperationContract(IsOneWay=true)] 
    void ProcessDivide(double num1, double num2); 
}    
public interface IServerFinishedProcessingCallback 
{   
    [OperationContract(IsOneWay=true)] 
    void ProcessingFinished(string operation, double result); 
} 

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class DualMathServiceClass : IDualMathService 
{ 
    readonly IServerFinishedProcessingCallback _clientCode = OperationContext.Current.GetCallbackChannel<IServerFinishedProcessingCallback>(); 
    //[PrincipalPermission()] 
    public void ProcessAdd(double num1, double num2) 
    { 
     Console.WriteLine("Processing Request for client session ID " + OperationContext.Current.SessionId); 
     Console.WriteLine(string.Format("Processing Add Request for parameters {0} and {1} ", num1, num2)); 
     _clientCode.ProcessingFinished("Add", (num1 + num2)); 
    } 
    public void ProcessSubtract(double num1, double num2) 
    { 
     Console.WriteLine("Processing Request for client session ID " + OperationContext.Current.SessionId); 
     Console.WriteLine(string.Format("Processing Subtract Request for parameters {0} and {1} ", num1, num2)); 
     _clientCode.ProcessingFinished("Subtract", (num1 - num2)); 
    } 
    public void ProcessMultiply(double num1, double num2) 
    { 
     Console.WriteLine("Processing Request for client session ID " + OperationContext.Current.SessionId); 
     Console.WriteLine(string.Format("Processing Multiply Request for parameters {0} and {1} ", num1, num2)); 
     _clientCode.ProcessingFinished("Multiply", (num1 * num2)); 
    } 
    public void ProcessDivide(double num1, double num2) 
    { 
     Console.WriteLine("Processing Request for client session ID " + OperationContext.Current.SessionId); 
     Console.WriteLine(string.Format("Processing Divide Request for parameters {0} and {1} ", num1, num2)); 
     if (num2 == 0) 
      throw new FaultException<string>("Number 2 can not be zer"); 
     _clientCode.ProcessingFinished("Divide", (num1/num2)); 
    } 
} 

Client Code

[CallbackBehavior(IncludeExceptionDetailInFaults = true, 
    UseSynchronizationContext = true, 
    ValidateMustUnderstand =true, 
    ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class ClientCallbackClass : IDualMathServiceCallback 
{ 
    public delegate void ProceFinishedEventDelegate(string operation, double result); 
    public event ProceFinishedEventDelegate ProcessFinishedEvent = null; 
    public void ProcessingFinished(string operation, double result) 
    {    
     if (ProcessFinishedEvent != null) 
     { 
      ProcessFinishedEvent(operation, result); 
     } 
    } 
} 
Смежные вопросы