wsHttpBinding not responsive after 10 calls
- Hi,
My WCF service is unresponsive after 10 calls (using wsHttpBinding, hosted in ServiceHost). Anybody got an idea what's going on? Looks like there's a session limit (MaxConcurrentSessions ), even though I explicitly declare to not use sessions. Not that client isn't closing the proxy, I don't want to rely on the client to do this. In .NET remoting the single call activation worked like a charm, can the same thing be achieved in WCF? Problem is similar to described here: http://stackoverflow.com/questions/832871/wcf-concurrent-requests-piling-up-on-the-server-when-using-wshttpbinding .
Server contract:
using System; using System.Collections.Generic; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; namespace BusinessApp.Data { /// <summary> /// Don't allow transport sessions. /// </summary> [ServiceContract(SessionMode = SessionMode.NotAllowed)] public interface IService { [OperationContract] List<Product> GetAllProducts(); [OperationContract] [CustomDataContractSerializer(true)] List<Category> GetAllCategories(); } }
Server:
using System; using System.Collections.Generic; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; using BusinessApp.Data; namespace BusinessApp.WcfService { [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any, InstanceContextMode = InstanceContextMode.Single)] public class Service : IService { private static int callNumber; public List<Product> GetAllProducts() { Console.WriteLine("{0}: GetAllProducts()", callNumber++); List<Product> products = new List<Product>(); products.Add(new Product { Name = "Apple", Description = "Juicy apple", Price = 1.20m }); products.Add(new Product { Name = "Tomato", Description = "Red tomato", Price = 1.35m }); return products; } public List<Category> GetAllCategories() { Console.WriteLine("{0}: GetAllCategories()", callNumber++); List<Category> categories = new List<Category>(); Category foodCategory = new Category { Name = "Food" }; foodCategory.Products.AddRange(GetAllProducts()); foodCategory.CheapestProduct = foodCategory.Products[0]; categories.Add(foodCategory); return categories; } } }
Client:
ChannelFactory<IService> channelFactory = new ChannelFactory<IService>("WsHttpService"); channelFactory.Credentials.UserName.UserName = "john"; channelFactory.Credentials.UserName.Password = "P@ssword"; IService service = channelFactory.CreateChannel(); List<Product> products = service.GetAllProducts();
Wout
Answers
- Hi, Wout.
Very interesting question!
I believe you should set EstablishSecurityContext property of WSHttpBinding to false.
var binding = new WSHttpBinding();
binding.Security.Message.EstablishSecurityContext = false;
It's needed to be done on both client and server.
Also check this:
http://blogs.msdn.com/drnick/archive/2009/07/15/load-balanced-web-service-bindings.aspx
Sergei Dorogin, Lead Developer, CROC Inc. (www.croc.ru)
All Replies
- Hi,
The wsHttpBinding will use secure sessions when you use username/password autthentication.
When you call the service, it is important to close the client procy after you have made the call, this will close the secure session.
If you want more cliennts to connect symaltaniously you can increase the maximum number of sessions.
Regards,
Alan
www.CloudCasts.net - Community Webcasts Powered by Azure - Hi Alan,
Thank you for your answer. So there is no way to automatically close the session server side after each call? This is how the old asmx web services worked, and I guess the current WCF BasicHttpBinding as well. If this is the case I'll have to switch to BasicHttpBinding, as this is the behavior that I want, because I don't want to rely on the client to close the session, as this would leave the server sensitive to a DOS attack. A bunch of clients not closing the session would tie the server up in a split second. Is this a design oversight in the wsHttpBinding?
Best regards,
Wout - Hi,
Sessions in WCF are different from ASP.NET sessions.
As for your scenario, I seem to remember there may be an option to supress the creation of secure sessions, but I'm not sure what it was (maybe i'm wrong here).
One option to protect against clients who forget to close the sessions is to set the receive timeout on the service binding configuration. THe defualt is 10 minutes, meaning that the session will live for 10 minutes without a call before it is closed by the service. If you reduce this you can minimize (but not eleminate) this.
Regards,
Alan
www.CloudCasts.net - Community Webcasts Powered by Azure - Hi Alan,
Yes, I was aware of the receive timeout, but the objective is to eliminate the session creation completely. For now I'll stick to BasicHttpBinding for better protection against dodgy clients.
Is there an official channel to request a feature? It would be nice to have an option for the WsHttpBinding to not create a session (which I thought the[ServiceContract(SessionMode = SessionMode.NotAllowed)]
did).
Thank you for you help,
Wout - Hi,
it seems something wrong with your Service Throttling configration.
for default the MaxConcurrentSessions is 10.
there are 3 Properties:MaxConcurrentCalls、MaxConcurrentSessions、MaxConcurrentInstances.
they default values are:16,10,26.
so if concurrency clients num more than 10,it will be dead locked and the 11th client can not receive any response until a timeout exception which will cause the cchannel faulted. and client can not use the channel.
So you can try to udapted the Throttling configration.
as following:
<serviceBehaviors>
<behavior name="WCFService.WCFServiceBehavior">
<serviceTimeouts transactionTimeout="00:01:00"/>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000"/>-->
</behavior>
</serviceBehaviors>
then set the behavior for your service.
regards
Frank Xu Lei--谦卑若愚,好学若饥
专注于.NET平台下分布式应用系统开发和企业应用系统集成
Focus on Distributed Applications Development and EAI based on .NET
欢迎访问老徐的中文技术博客:Welcome to My Chinese Technical Blog
欢迎访问微软WCF中文技术论坛:Welcome to Microsoft Chinese WCF Forum
欢迎访问微软WCF英文技术论坛:Welcome to Microsoft English WCF Forum - Hi Frank Xu Lei,
I'm aware of throttling, but problem is I don't want 1000 dangling sessions, because both 10 or 1000 don't really protect against DOS attacks. The server will still hang within a split second if the client doesn't close the session.
What I want is to create no sessions at all, or automatically kill the session on the server side as soon as the call is completed.
Best regards,
Wout
- Hi Wout,
Yes, you can turn off reliableSession for wshttpbinding with two settings:
1. mark your serviceContract as SessionMode=NotAllowed(as you mentioned in previous message)
2. In binding config, turn off the reliableSession as below:
<bindings> <wsHttpBinding> <binding name="Binding1" > <reliableSession enabled="false"/> <security mode= "None"></security> </binding> </wsHttpBinding> </bindings>
Also, if message secuirty is not necessary for your scenario, I think basicHttpBinding is good enough.
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- Proposed As Answer bySteven Cheng - MSFTMSFT, ModeratorTuesday, October 06, 2009 2:02 AM
- Unproposed As Answer byWout Wednesday, October 07, 2009 7:53 AM
- Marked As Answer bySteven Cheng - MSFTMSFT, ModeratorWednesday, October 07, 2009 2:02 AM
- Unmarked As Answer byWout Wednesday, October 07, 2009 7:51 AM
- Proposed As Answer byQyl Tuesday, November 03, 2009 9:24 PM
- Marked As Answer byWout Thursday, November 12, 2009 12:16 PM
- Unmarked As Answer byWout Thursday, November 12, 2009 12:21 PM
- What if you increast the concurrent calls in service throtling behaviour
<serviceThrottling
maxConcurrentCalls="100"
maxConcurrentSessions="100"
maxConcurrentInstances="100"
/>
Rohan Fernando Reffer this
http://stackoverflow.com/questions/480020/wcf-service-throttling
Rohan Fernando- Hi Steven,
I have tried setting reliableSession enabled to false in the server configuration, but the behavior remains exactly the same, still need to close the session explicitly on the client. Thank you for the reply though.
Wout
- Did u close the service after calling the method?
- Hi,
When you set ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, and cehck OperationContext.Current.SessionId inside the operation you will see that session is null. That i guess means sessions are not enabled. Or you can try setting the following which didnt allow me to create more than 25 client proxies. If your not interested in sessions at all then you can try percall instance mode. Or last but not least you try setting ReleaseInstancemode in you service bevaior to AfterCall. But than that will result in a per call service.
<
serviceBehaviors>
<behavior name="CustomUserNameValidator.Service1Behavior">
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="CustomUserNameValidator.MyUserNamePasswordValidator, CustomUserNameValidator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</serviceCredentials><!--
To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<
serviceMetadata httpsGetEnabled="true"/>
<!--
To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<
serviceDebug includeExceptionDetailInFaults="false"/>
<
serviceThrottling maxConcurrentSessions="25"/>
</
behavior>
</
serviceBehaviors>
- Hi, Wout.
Very interesting question!
I believe you should set EstablishSecurityContext property of WSHttpBinding to false.
var binding = new WSHttpBinding();
binding.Security.Message.EstablishSecurityContext = false;
It's needed to be done on both client and server.
Also check this:
http://blogs.msdn.com/drnick/archive/2009/07/15/load-balanced-web-service-bindings.aspx
Sergei Dorogin, Lead Developer, CROC Inc. (www.croc.ru) - I had the same x call problem with wsHttpBinding. I used the varous suggestions from this forum and this is what finally worked:
Set SessionMode to NotAllowed on service interface:
[ServiceContract(SessionMode=SessionMode.NotAllowed)] public interface IMainServiceDO NOT set InstanceContextMode.PerCall on the class (don't know if this matters)
Add Bindings section to config file with reliableSession enabled = false, security mode=Message, establishSecurityContext=false:
So far this is allowing me to have no session with wsHttpBinding, so I am a happy camper, thanks for all the help!<service behaviorConfiguration="SixService.MainServiceBehavior" name="SixService.MainService"> <endpoint address="" binding="wsHttpBinding" bindingConfiguration="Binding1" contract="SixService.IMainService"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <bindings> <wsHttpBinding> <binding name="Binding1"> <reliableSession enabled="false" /> <security mode="Message"> <message establishSecurityContext="false" /> </security> </binding> </wsHttpBinding> </bindings> - Hi Sergei,
I have just tested and verified that this does solve the issue! I'm very glad you found it, I was already surprised that the wsHttpBinding didn't allow this. I now add this binding's security's message configuration at the server side:
<message clientCredentialType="UserName" establishSecurityContext="false" />
At the client side I set the binding's security's message establishSecurityContext to false:
<message clientCredentialType="UserName" establishSecurityContext="false" />
So now the server configuration eliminates the existence of these sessions, correct?
However!!! Have any idea what the difference is between property WSHttpBindingBase.ReliableSession.Enabled and WSHttpBinding.Security.Message.EstablishSecurityContext?
Many thanks!
Wout - Hi Steven,
Have any idea what the difference is between property WSHttpBindingBase.ReliableSession.Enabled and WSHttpBinding.Security.Message.EstablishSecurityContext?
Thank you for your help!
Wout - Oops, revisited the server config again. It was definitely not
<reliableSession enabled="false" />that did the trick. I had it in there, which made me think that made it work, but it was this that did make it work:
<message clientCredentialType="UserName" establishSecurityContext="false" /
Apologies for the confusion! But I'm glad everything is adding up it's working properly now!
Wout


