Question

In the project I'm working on, we have several services implemented using WCF. The situation I'm facing is that some of the services need to know when a session ends, so that it can appropriately update the status of that client. Notifying the service when a client gracefully terminates (e.g. the user closes the application) is easy, however, there are cases where the application might crash, or the client machine might restart, in which case the client won't be able to notify the service about its status.

Initially, I was thinking about having a timer on the server side, which is triggered once a client connects, and changes the status of that client to "terminated" after, let's say, 1 minute. Now the client sends its status every 30 seconds to the service, and the service basically restarts its timer on every request from the client, which means it (hopefully) never changes the status of the client as long as the client is alive.

Even though this method is pretty reliable (not fully reliable; what if it takes the client more than 1 minute to send its status?) it's still not the best approach to solving this problem. Note that due to the original design of the system, I cannot implement a duplex service, which would probably make things a lot simpler. So my question is: Is there a way for the sevice to know when the session ends (i.e. the connection times out or the client closes the proxy)? I came accross this question: WCF: How to find out when a session is ending but the link on the answer seems to be broken.

Another thing that I'm worried about is; they way I'm currently creating my channel proxies is implemented like this:

  internal static TResult ExecuteAndReturn<TProxy, TResult>(Func<TProxy, TResult> delegateToExecute)
  {
      string endpointUri = ServiceEndpoints.GetServiceEndpoint(typeof(TProxy));

      var binding = new WSHttpBinding();
      binding.Security.Mode = SecurityMode.Message;
      binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;

      TResult valueToReturn;

      using (ChannelFactory<TProxy> factory = new ChannelFactory<TProxy>(binding,
                                                                               new EndpointAddress(new Uri(endpointUri), 
                                                                               EndpointIdentity.CreateDnsIdentity(ServiceEndpoints.CertificateName))))
      {
          TProxy proxy = factory.CreateChannel();

          valueToReturn = delegateToExecute(proxy);
      }

      return valueToReturn;
  }

So the channel is closed immediately after the service call is made (since it's in a using block), is that, from a service standpoint, an indication that the session is terminated? If so, should I keep only one instance of each service during application runtime, by using a singleton maybe? I apologize if the questions seem a little vague, I figured there would be plenty of questions like these but wasn't able to find something similar.

No correct solution

OTHER TIPS

Yes, closing the channel terminates the session, but if there is an error of some kind then you are subject to the timeout settings of the service, like this:

<binding name="tcpBinding" receiveTimeout="00:00:10" />

This introduces a ten second timeout if an error occurs.

Check out Managing WCF Session Lifetime with IsInitiating and IsTerminating

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top