I have WCF service consumed by AJAX client using SOAP 1.2
Web.config:
<endpoint address="" binding="wsHttpBinding"
contract="WcfService1.IService1" bindingConfiguration="wsHttpBin">
<wsHttpBinding>
<binding name="wsHttpBin">
<security mode="None"/>
</binding>
</wsHttpBinding>
From what I have read, I have to use <security mode="None"/>
since a service exposed with “wsHttpBinding” binding implements WS-Security of WS-* family of web service specifications. As the binding uses security, the request will be rejected since AJAX doesn't support the security context.
My WCF service behavior is defined with InstanceContextMode.PerSession
:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.PerSession)]
but when I consume it, the service behave as PerCall and every call starts a new WCF instance instead of using the current instance.
Why InstanceContextMode.PerSession behave like PerCall when using wsHttpBinding?
What can I do?
Sessions, when used over HTTP, are only supported by WCF when using security sessions or reliable sessions. If you can't use either then you have to implement a session mechanism by yourself. If you control both the client and the server side, it would be quite easy to do it. Here's how:
Create a class that holds all the session data you need stored (let's call it SessionData
), plus an additional DateTime
for when the session was last used. Then add to your service class (or any other class) a static
ConcurrentDictionary<string, SessionData>
.
When a client makes a call to your service, require it to pass a unique string that identifies the session (it can be randomly generated on the client side). Whenever a client calls you service, look up the session string in the dictionary and retrieve the session data (and update its content as needed). If it doesn't exist, create a new entry in the dictionary. Also, every time you access the SessionData
object, update the 'last used' DateTime
to the current time. A background task should periodically clear out old sessions that haven't been used in a while.
That's it - you've implemented sessions on your own. You can now useInstanceContextMode.Single
and not worry about WCF correctly creating instances of your service class per session.
EDIT: If you're writing your WCF service with .NET 4.5 and you web application only targets modern browsers, you can use NetHttpBinding
on the server side and WebSocket on the client side. NetHttpBinding
supports session (when specifying SessionMode.Required
).
This link gives You pretty much all You need to know about this (in general of course).
But to precise. Msdn says about WCF session:
They are explicitly initiated and terminated by the calling
application
I must say that I don't know about any JS code/framework that would allow You to store explicitly opened WCF communication channel to keep Your "session" alive. (You haven't provided your client code so I must make some assumptions).
WCF session is not "cookie-based". It doesn't work "out of the box" from your browser like it would for ASP.NET web application.
Setting InstanceContextMode.PerSession
makes Your WCF service "session-ready" but it is not enough to "force" a session.