How to fix basicHttpBinding in WCF when using multiple proxy clients?
- by Hemant
[Question seems a little long but please have patience. It has sample source to explain the problem.]
Consider following code which is essentially a WCF host:
[ServiceContract (Namespace = "http://www.mightycalc.com")]
interface ICalculator
{
[OperationContract]
int Add (int aNum1, int aNum2);
}
[ServiceBehavior (InstanceContextMode = InstanceContextMode.PerCall)]
class Calculator: ICalculator
{
public int Add (int aNum1, int aNum2) {
Thread.Sleep (2000); //Simulate a lengthy operation
return aNum1 + aNum2;
}
}
class Program
{
static void Main (string[] args) {
try {
using (var serviceHost = new ServiceHost (typeof (Calculator))) {
var httpBinding = new BasicHttpBinding (BasicHttpSecurityMode.None);
serviceHost.AddServiceEndpoint (typeof (ICalculator), httpBinding, "http://172.16.9.191:2221/calc");
serviceHost.Open ();
Console.WriteLine ("Service is running. ENJOY!!!");
Console.WriteLine ("Type 'stop' and hit enter to stop the service.");
Console.ReadLine ();
if (serviceHost.State == CommunicationState.Opened)
serviceHost.Close ();
}
}
catch (Exception e) {
Console.WriteLine (e);
Console.ReadLine ();
}
}
}
Also the WCF client program is:
class Program
{
static int COUNT = 0;
static Timer timer = null;
static void Main (string[] args) {
var threads = new Thread[10];
for (int i = 0; i < threads.Length; i++) {
threads[i] = new Thread (Calculate);
threads[i].Start (null);
}
timer = new Timer (o => Console.WriteLine ("Count: {0}", COUNT), null, 1000, 1000);
Console.ReadLine ();
timer.Dispose ();
}
static void Calculate (object state)
{
var c = new CalculatorClient ("BasicHttpBinding_ICalculator");
c.Open ();
while (true) {
try {
var sum = c.Add (2, 3);
Interlocked.Increment (ref COUNT);
}
catch (Exception ex) {
Console.WriteLine ("Error on thread {0}: {1}", Thread.CurrentThread.Name, ex.GetType ());
break;
}
}
c.Close ();
}
}
Basically, I am creating 10 proxy clients and then repeatedly calling Add service method on separate threads. Now if I run both applications and observe opened TCP connections using netstat, I find that:
If both client and server are running on same machine, number of tcp connections are equal to number of proxy objects. It means all requests are being served in parallel. Which is good.
If I run server on a separate machine, I observed that maximum 2 TCP connections are opened regardless of the number of proxy objects I create. Only 2 requests run in parallel. It hurts the processing speed badly.
If I switch to net.tcp binding, everything works fine (a separate TCP connection for each proxy object even if they are running on different machines).
I am very confused and unable to make the basicHttpBinding use more TCP connections. I know it is a long question, but please help!