Showing posts with label WCF. Show all posts
Showing posts with label WCF. Show all posts

Monday, March 2, 2009

The order of service call

By default the service call can be called without any pre-defined order. Microsoft provide a proprietary feature to support ordered call. This is only meaningful only when session is supported. IsInitiating and IsTerminating are two properties of OperationContract attribute. By default IsInitiating is true, means it can be called first in a session. IsTerminating is false by default, means the session can call other service after this call.

ServiceContract vs ServiceBehavior

In WCF, ServiceContract attribute affect the behavior of both client and server, while ServiceBehavior only affect the behavior of server. ServiceContract can apply both to interface and class, but ServiceBehavior can only apply to class implementation. ServiceContract affect the wsdl emitted, but ServiceBehavior will not affect wsdl emitted.

public enum SessionMode { Allowed, Required, NotAllowed } [AttributeUsage(AttributeTargets.Interface|AttributeTargets.Class, Inherited=false)] public sealed class ServiceContractAttribute : Attribute { public SessionMode SessionMode {get;set;} //More members } [AttributeUsage(AttributeTargets.Class)] public sealed class ServiceBehaviorAttribute : Attribute, IServiceBehavior { } // Summary: // Specifies the number of service instances available for handling calls that // are contained in incoming messages. public enum InstanceContextMode { // Summary: // A new System.ServiceModel.InstanceContext object is created for each session. PerSession = 0, // // Summary: // A new System.ServiceModel.InstanceContext object is created prior to and // recycled subsequent to each call. If the channel does not create a session // this value behaves as if it were System.ServiceModel.InstanceContextMode.PerCall. PerCall = 1, // // Summary: // Only one System.ServiceModel.InstanceContext object is used for all incoming // calls and is not recycled subsequent to the calls. If a service object does // not exist, one is created. Single = 2, }

InstanceContextMode is a property of ServiceBehavior attribute, it affect server only. Its default value is PerSession.PerSession, but PerCall can get the best scalability, which is generally recommended. But PerSession is not compatible with transport protocol binding like basicHttpBinding. And the implementation requires to follow IDisposable pattern and Session retore pattern to support PerCall behavior.

SessionMode mode is a property of ServiceContract, it affect both the client. It is default value is "Allowed". It tells the client whether it should keep a session with server. When you create proxy at client side, that proxy will create a session in first call. If you create another proxy, that will create a new session. In order to correlate all messages from a particular client to a particular instance, WCF needs to be able to identify the client. One way of doing that is to rely on a transport-level session; that is, a continuous connection at the transport level, such as the one maintained by the TCP and IPC protocols. As a result, when using the NetTcpBinding or the NetNamedPipeBinding, WCF associates that connection with the client. The situation is more complex when it comes to the connectionless nature of the HTTP protocol. Conceptually, each message over HTTP reaches the services on a new connection. Consequently, you cannot maintain a transport-level session over the BasicHttpBinding. The WS binding, on the other hand, is capable of emulating a transport-level session by including a logical session ID in the message headers that uniquely identifies the client. In fact, the WSHttpBinding will emulate a transport session whenever security or reliable messaging is enabled.

When we implement our service, we can use different combination of SessionMode(client), InstanceContextMode(server), and transporation binding. SessionMode and InstanceContextMode has no configuration confict, which means any SessionMode can go with any InstanceContextMode. But there are some design conflict. For example, SessionMode.NotAllowed does not go with InstanceContextMode.PerSession very well. To maintain a instance per session, client should support session as well. If client does not allowed session, every service call is treated as new session. But it will not caused configuration error. To support SessionMode.Required, binding can not be basicHttpBinding. The combination of SessionMode.Required and basicHttpBinding will generate a configuration error. InstanceContextMode.PerSession can works with basicHttpBinding, but every service call will treated as new session.

Friday, December 12, 2008

WCF transport-level session

All bindings support configuring the contract on the endpoint with SessionMode.Allowed. The SessionMode property does not refer to the instancing mode, but rather to the presence of a transport-level session (or its emulation in the case of the WS bindings). As its name implies, when the SessionMode property is configured with SessionMode.Allowed, it merely allows transport sessions, but does not enforce it. The exact resulting behavior is a product of the service configuration and the binding used. If the service is configured for per-call, it still behaves as per-call service. When the service is configured for a per-session service, it will behave as a per-session service only if the binding used maintains a transport-level session. For example, the BasicHttpBinding can never have a transport-level session due to the connectionless nature of the HTTP protocol. The WSHttpBinding without security and without reliable messaging will also not maintain a transport-level session. In both of these cases, even though the service is configured with InstanceContextMode.PerSession and the contract with SessionMode.Allowed, the service will behave as a per-call service, and the calls to Dispose() are asynchronous; that is, the client is not blocked after the call while WCF disposes of the instance.