Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF, Duplex callback, recieveTimeout netTcpBinding

Ive got a Host / Client WCF Service and client that is using netTcpBinding and a callback method.

<bindings>
      <netTcpBinding>
        <binding name="tcp_Unsecured" receiveTimeout="00:01:00" sendTimeout="00:01:00">
          <security mode="None" />
          <reliableSession enabled="true" ordered="true" inactivityTimeout="00:10:00"/>
        </binding>
      </netTcpBinding>
</bindings>

Proxy

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples", ConfigurationName="AlarmServer", CallbackContract=typeof(AlarmServerCallback), SessionMode=System.ServiceModel.SessionMode.Required)]
public interface AlarmServer
{

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/RegisterAlarm")]
    void RegisterAlarm(System.DateTime alarmTime, string clientName, string reminderMessage);

    [System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/unRegisterAlarm")]
    void unRegisterAlarm(string clientName);

    [System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/broadcastMessage")]
    void broadcastMessage(string msg);
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface AlarmServerCallback
{

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/SignalAlarm")]
    void SignalAlarm(string reminderMessage);

    [System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/displayMessage")]
    void displayMessage(string msg);
}

client instance with callback

public MainForm()
{
    InitializeComponent();
    InstanceContext context = new InstanceContext(new AlarmCallback());
    client = new AlarmServerClient(context);
}

The problem I have is that after the binding recieveTimeout triggers, the client goes into a faulted state and closes the clients listening callback.

I can see the listening port drop using TCPVIEW from sysinternals.

If I keep the channel busy, the time out does not trigger, so its not a fault in the WCF message to the Server/Client, as multiple messages will flow through ok.

I thought the receiveTimeout was designed to provide a way to detect if a reply from the WCF message over TCP failed? Why is it faulting the connection. It almost appears that if there are no callback object created for the timeout period, the channel is then closed?

What am I doing wrong?

like image 534
PrimeTSS Avatar asked May 12 '10 13:05

PrimeTSS


2 Answers

Seems the Receivetime out causes the callback host service to fault after it reaches its max count. Which is 23.59 hrs or the default of 1 minute. I can resolved the timeout issue with setting receivetimeout to Infinate

 <bindings>
      <netTcpBinding>
        <binding name="NetTcpBinding_AlarmServer" receiveTimeout="infinite" >
          <security mode="None" />        
        </binding>
      </netTcpBinding>
    </bindings>

But this has me now wondering if im really using the right tool in WFC for Server/Client communications. I want a Host/Server to be running on a file server, and multiple remote clients connected to it. The client will ping the server with a heartbeat, and occasionally the server might send a command to the client. I was doing this with remoting or tcpsockets and using a "client polling method", where commands where quued in a database and when the client polled the server for a command every 10 mins, if there was a pending command for that unique client it got it. This worked ok, and had the advantage of NOT having 1000 open tcp socket connections to the server, as client would only randomly connect and disconnect. BUT I decided to try WCF (after all isnt this the new latest in greates replacing Remoting?) and when I found Duplex I thought, Id use it.... NOW Im thinking Im missing the point about what WCF Duplux is for ???

Help am I missing the concepts here???

like image 116
PrimeTSS Avatar answered Oct 31 '22 10:10

PrimeTSS


The value at which the receiveTimeout is set will tell the service how long to wait before faulting the communication channel when no application message is received. You can always increase this timeout value to a greater number (default is 10 minutes), but you then also have to increase the session inactivity timeout. Please see http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.binding.receivetimeout.aspx for more information on both of these timeouts.

When the receive or inactivity timeout fires, the duplex channel is faulted. You will have to create a new proxy on the client side to be able to communicate with the server again.

You can always check the channel connection status on the client side before trying to call the server. If the CommunicationState of the channel is not opened, then you can create a new proxy before calling the server.

like image 32
jiboutin Avatar answered Oct 31 '22 10:10

jiboutin