WCF Design questions - wcf

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?

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.

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.

Related

Reuse WCF server instance between operations, without concurrency

How can I make the WCF server instance (the instance of the class in the .svc.cs / .svc.vb file) stay alive between requests?
It's a stateless, read-only type of service: I'm fine with different clients reusing the same instance. However, it's not thread-safe: I don't want two threads to execute a method on this instance concurrently.
Ideally, what I'm looking for is that WCF manages a "worker pool" of these instances. Say, 10. New request comes in: fetch an instance, handle the request. Request over, go back to the pool. Already 10 concurrent requests running? Pause the 11th until a new worker is free.
What I /don't/ want is per-client sessions. Startup for these instances is expensive, I don't want to do that every time a new client connects.
Another thing I don't want: dealing with this client-side. This is not the responsibility of the client, which should know nothing about the implementation of the server. And I can't always control that.
I'm getting a bit lost in unfamiliar terminology from the MSDN docs. I have a lot working, but this pool system I just can't seem to get right.
Do I have to create a static pool and manage it myself?
Thanks
PS: A source of confusion for me is that almost anything in this regard points toward the configuration of the bindings. Like basicHttp or wsHttp. But that doesn't sound right: this should be on a higher level, unrelated to the binding: this is about the worker managers. Or not?
In the event that you have a WCF service that centralizes business logic, provides/controls access to another “single” backend resource (e.g. data file, network socket) or otherwise contains some type of shared resource, then you most likely need to implement a singleton.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
In general, use a singleton object if it maps well to a natural singleton in the application domain. A singleton implies the singleton has some valuable state that you want to share across multiple clients. The problem is that when multiple clients connect to the singleton, they may all do so concurrently on multiple worker threads. The singleton must synchronize access to its state to avoid state corruption. This in turn means that only one client at a time can access the singleton. This may degrade responsiveness and availability to the point that the singleton is unusable as the system grows.
The singleton service is the ultimate shareable service, which has both pros(as indicated above) and cons (as implied in your question, you have to manage thread safety). When a service is configured as a singleton, all clients get connected to the same single well-known instance independently of each other, regardless of which endpoint of the service they connect to. The singleton service lives forever, and is only disposed of once the host shuts down. The singleton is created exactly once when the host is created.
https://msdn.microsoft.com/en-us/magazine/cc163590.aspx

Check for Presence of WCF Transport Session

Given a svcutil generated WCF client, is there a way to query the client to find out if transport session is being used by the underlying binding?
I'd like to dynamically check this so that I can write a WCF client wrapper which opens and closes the proxy safely while accounting for channel-fault cases that only apply when transport session is in play.
I see there is a MyClient.InnerChannel.SessionID which may be helpful. Perhaps if it is non-null it implies that transport session is active. But I think that is perhaps too big of an assumption. For example, I understand wsHttpBinding can emulate transport session. When that happens, the SessionId may be non-null and yet presumably there would not be a true transport session that could be faulted.
I also see I can peek at MyClient.ChannelFactory.Endpoing.Binding, but I'm not sure from there what might provide a clue.

Recommended WCF client channel lifetime with Message security

I have a question with regards to WCF client channel lifetime while using Message security, but first, a few notes on my company's setup and guidelines:
Our client-server applications are solely for intranet use
Our clients are WPF applications
Our company's guidelines for WCF usage are:
Use wsHttpBinding
Use Message Security
Service InstanceMode: PerCall
Service ConcurrencyMode: Multiple
It is the first time I have to use message security on an intranet setup. Here's how I typically use my client channels to limit the amount of resources kept on the client and server and literally just to keep things simple:
Instantiate + open channel (with ChannelFactory)
Make the WCF call
Close / dispose the channel asap
While monitoring this strategy with Fiddler 2, I noticed that because of Message Security, a single WCF call ended up causing 5 round-trips to my service:
3 initial round-trips for handshaking
1 round-trip for the actual WCF call
1 call to close the session (since I am using PerCall, I am assuming this is more a security session at the IIS level)
If I were to turn off Message Security, as one would expect, one WCF ended up being... A single round-trip.
As of now, I must use Message Security because that's our guideline. With this in mind and knowing that we make hundreds of WCF calls from each client WPF app a session, would you therefore advise to open the client channel and keep it open for re-use instead of disposing of it every time?
I would advise not to preemptively turn off features until you know they are a known problem. Preoptimization is needless work. Until you notice your clients having lagging problems, I would not worry about the message security. At that point, try a few things: one of your approaches of keeping a client open longer; two, try grouping requests together without turning off message security; three, consider caching, if you can; four, if the message security is the final culprit, then try a different method. I wouldn't just turn something off because I see a bit more network traffic until I knew it was the absolute last thing that I could do to improve performance.

Wcf Throttling and InstanceContextMode.PerSession behaviour

I'm quite misunderstanding the InstanceContextMode.PerSession behavior.
I know about if we want to connect the client with dedicated session, which mean when a client connect the service a session will hold all its calls till the client close the connection.
So is this scenario what is the PerSession behaviour mean or something else.
and in the Throttling we have the MaxConcurrentSessions .
My question : If we declare the InstanceContextMode with PerCall does is the same mean of session dedicated for each client and how the MaxConcurrentSessions affects the PerCall behaviour .
Per call means that for each call a new instance of the service is created to process the call. So there is no possibility of session state being maintained between calls. I suspect that the throttling setting has no effect in this case.

How can I share one session between several wcf's clients?

I have several web services. One of this services is used for retrieve a session id (authentication). I pass this id when call other services through SessionInfo.
I want to use WCF instead of classic web methods. How can I share one session between several wcf's clients?
It is not clear what do you mean by session. WCF supports four types of sessions:
Transport session - for transport protocol which maintains session between server and client. For example: Net.Tcp, Net.Pipe
Reliable session - support for reliable in order delivery over unreliable channel if both client and server are running
Security session - client has to be authenticated only for the first call, subsequent calls are authenticated by session token. This session is also called security context.
Application session - this has a meaning for IsInitiating and IsTerminating parameters of operation contract and PerSession instancing. This session can be used only if any of preceding sessions is used as well = it can't be used in BasicHttpBinding because it doesn't support transport, reliable and security session.
All these sessions are related to communication between single client proxy and single service instance. Nothing else is provided out of the box. Moreover there is no special "session" object.
So what exactly are you trying to achieve? Are you going to replace ASMX services wich are using ASP.NET session? In that case check this sample.
Edit:
The idea about receiving single Id from the first service and reusing this Id on subsequent calls to multiple services should be called corelation (one big activity/transaction) or federation (security related) not session.
As marc_s says you cannot share the session.
But what you can do is to pass the session id as a parameter in your WCF calls, so that you know on whos behalf the call is being made.
Make sure that you use encryption on these calls.
The recommanded way to that is by manually maintaining session state between calls. You generate session IDs the way you want and load/persist session information into a database on every call using your own logic.
By doing that, you will support sessions in a way that will enable:
Load balancing
Session sharing
Fail over