WCF, Duplex callback, recieveTimeout netTcpBinding

PrimeTSS picture PrimeTSS · May 12, 2010 · Viewed 11.2k times · Source

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?

Answer

PrimeTSS picture PrimeTSS · May 14, 2010

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