Transport-Level Sessions

In traditional programming, an object is indirectly associated with a client by virtue of the call stack. That is, each object is tied to a particular client. But in WCF, since the client sends a message to the service and never invokes the instance directly, such an association is not possible. The analogous concept in WCF is the transport session, which ensures that all messages coming from a particular client are sent to the same transport channel on the host. It is as if the client and the channel maintain a logical session at the transport level (hence the name). As in traditional programming, with a transport session the calls (or rather, the messages) are strictly processed in the order in which they were received. The transport session is unrelated to any application-level session the client may or may not have with the instance itself. Note that using a transport session is optional and is largely an aspect of the binding configuration, so the client and the service may or may not have a transport session. The transport session is one of the key fundamental concepts of WCF, affecting reliability, instance management, error management, synchronization, transactions, and security.

A transport session relies on WCF's ability to identify the client and correlate all its messages to a particular channel. Thus, there has to be something in the transport or in the message that identifies the client.

Transport Session and Binding

Both the TCP and the IPC bindings are connection-full. That is, all calls from the client come on the same connection or pipe, enabling WCF to easily identify the client. However, HTTP is by definition a connectionless protocol, and every message from the client comes on a new connection. Consequently, when using the basic binding, there is never a transport session; or, more precisely, there is a transport session, but it lasts for only one call, and after the call returns the channel is destroyed along with the connection. The next call will come on a new connection and will be routed to a new channel. The WS binding can improve on this situation by emulating a transport session. If configured to do so, it will insert in each message a unique ID identifying the client and will keep sending this ID for every call from that client. You will see more about that ID in Chapter 4.

Transport Session Termination

Typically, the transport session will end once the client closes the proxy. However, in case the client terminates ungracefully or in case of a communication problem, each transport session also has an idle-time timeout that defaults to 10 minutes. The transport session will automatically terminate after 10 minutes of inactivity from the client, even if the client still intends to use the proxy. If the client tries to use its proxy after the transport session has been terminated due to the idle timeout, it will get a CommunicationObjectFaultedException. Both the client and the service can configure a different timeout by setting a different value in the binding. The bindings that support a transport-level session provide the ReliableSession property, which can be of the type ReliableSession or OptionalReliableSession. The ReliableSession class offers the InactivityTimeout property, which you can use to configure a new idle-time timeout:

public class ReliableSession
{
   public TimeSpan InactivityTimeout
   {get;set;}
   //More members
}
public class OptionalReliableSession : ReliableSession
{...}
public class NetTcpBinding : Binding,...
{
   public OptionalReliableSession ReliableSession
   {get;}
   //More members
}
public abstract class WSHttpBindingBase : ...
{
   public OptionalReliableSession ReliableSession
   {get;}
   //More members
}
public class WSHttpBinding : WSHttpBindingBase,...
{...}
public class WSDualHttpBinding : Binding,...
{
   public ReliableSession ReliableSession
   {get;}
   //More members
}

For example, here is the code required to programmatically configure an idle timeout of 25 minutes for the TCP binding:

NetTcpBinding tcpSessionBinding = new NetTcpBinding(  );
tcpSessionBinding.ReliableSession.InactivityTimeout = TimeSpan.FromMinutes(25);

Here is the equivalent configuration setting using a config file:

<netTcpBinding>
   <binding name = "TCPSession">
      <reliableSession inactivityTimeout = "00:25:00"/>
   </binding>
</netTcpBinding>

If both the client and the service configure a timeout, the shorter timeout prevails.

Tip

There is another esoteric service-side configuration for session termination: the ServiceBehavior attribute offers an advanced option for managing session shutdown via the AutomaticSessionShutdown property. This property is intended for optimizing certain callback scenarios, and it can safely be ignored in most cases. In a nutshell, AutomaticSessionShutdown defaults to true so that when the client closes the proxy, the session is terminated. Setting it to false causes the session to continue until the service explicitly closes its sending channel. When this attribute is set to false, the client of a duplex session (discussed in Chapter 5) must manually close the output session on the duplex client channel; otherwise, the client will hang waiting for the session to terminate.

Get Programming WCF Services, 2nd Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.