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.
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 a unique ID identifying the client in each message and will keep sending this ID for every call from that client. You will see more about this ID in Chapter 4.
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
. You can configure different timeouts on the client and
the service by setting different values 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;set} //More members } public abstract class WSHttpBindingBase : ... { public OptionalReliableSession ReliableSession {get;set} //More members } public class WSHttpBinding : WSHttpBindingBase,... {...}
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.
Note
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 you can safely ignore it in
most cases. In a nutshell, Automatic
Session
Shutdown
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, 3rd 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.