tags:

views:

144

answers:

2

I am designing a WCF service. I am using netTCP binding. The Service could be called from multi-threaded clients. The multi-threaded clients are not sharing the proxy.

1. WCF Service design question.

Client has to sent these 2 values in every call: UserID and SourceSystemID. This will help the Service to identify the user and the system he belongs. Instead of passing these 2 values in every call, I decided to have them cached with the Service for the duration of call from the client. I decided to have a parameterized constructor for the Service and store these values in the ChannelContext as explained in this article. http://www.danrigsby.com/blog/index.php/2008/09/21/using-icontextchannel-extensions-to-store-custom-data/

Initially I wanted to go with storing the values in the Session and have a method for initialization and termination. But there I found that I need to manually clean up the session in each case. When I am storing values in the channel context, I don’t have to clean it up every time and when the channel closes the values stored are already destroyed. Can somebody please make sure that I am correct in my assumption?

2. Should I use SessionMode? For my contract, I used : [ServiceContract(SessionMode = SessionMode.Required)] and without this service attribute.

Irrespective of my choice, I am always finding a value for : System.ServiceModel.OperationContext.Current.SessionId How can this be explained?

When I say SessionMode.Required, does my InstanceContextMode automatically change to PerSession?

3. InstanceContextMode to be used? My service is stateless except that I am storing some values in the Channel Context as mentioned in (1). Should I use Percall or PerSession as InstanceContextMode?

+1  A: 

The netTcp always has a transport-level session going - so that's why you always have a SessionId. So basically, no matter what you choose, with netTcp, you've got a session-ful connection right from the transport level on up.

As for InstanceContextMode - as long as you don't need anything else from a session except the SessionId - no reliable messaging etc. - then I'd typically pick Per-Call - it's more scalable, it typically performs better, it gives you less "glue" to worry about and less bits and pieces that you need to manage.

I would use an explicitly required session only if you need to turn on reliable messaging or something else that absolutely requires a WCF session. If you don't - then it's just unnecessary overhead, in my opinion.

marc_s
A: 

Setting SessionMode to SessionMode.Required will enforce using bindings which support sessions, like NetTcpBinding, WSHttpBinding, etc. In fact if you try using a non-session-enabled binding , the runtime will throw an exception when you try to open the host.

Setting InstanceContextMode to PerSession means that only one instance of the service will be crated per session and that instance will serve all the requests coming from that session.

Having SessionId set by the runtime means that you might have a transport session or a reliable session or security session. Having those does not necessarily mean you have an application session , that is a single service object serving the requests per proxy. In other words, you might switch off application session by setting InstanceContextMode=PerCall forcing the creation of a new service object for every call, while maintaining a transport session due to using netTcpBinding, or a reliable or security session.

Think of the application session that is configured by InstanceContextMode and Session Mode as a higher level session, relying on a lower-level session /security, transport or reliable/. An application session cannot actually be established without having one of the other sessions in place, from there the requirement for the binding .

It is getting a bit long already, but for simple values I would recommend you to pass those values every time instead of creating application session. That will ensure the service objects have a short lifetime and no unnecessary resources will be kept alive on the server. It makes a lot sense with more clients, or proxies talking to your service. And you could always cache the values in the clients, even pass them as custom headers if you want.

Petar Kabashki
Thanks for the great insight about Sessions. Currently I am using transport level session and have disabled the application session by using PerCall.