简体   繁体   中英

WCF service callback not called

I am using tcp binding in WCF service and my callback at client side in not getting called.This is my code

Service

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

    }       
}

and my client is

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

    }
}

I face two issues:

1.I dont receive callback from DoSomething with above mentioned code. 2.If I declare DoSomething as Twoway ,I do receive callback but it throws exception "Server did not provide a meaningful reply"

My client config

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

my Service config

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

The problem is, you're calling the service again from the callback. If you would leave this out, there's no error about "no meaningful answer".

It should help to set ConcurrencyMode attribute to your service and callback class:

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

and

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

You must set "IsOneWay = false" in the OperationContract, of course.

It should work using IsOneWay = true..

Here is an example

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM