2010-03-17 61 views
3

[問題似乎有點長,但請耐心等待。它有樣品來源問題的解釋]如何在使用多個代理客戶端時修復WCF中的basicHttpBinding?

考慮下面的代碼基本上是一個WCF主持人:

[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(); 
     } 
    } 
} 

而且WCF客戶端程序是:

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(); 
    } 
} 

基本上,我創建10個代理客戶端,然後在單獨的線程上重複調用Add service方法。現在,如果我同時運行的應用程序和用netstat觀察打開的TCP連接,我發現:

  • 如果客戶端和服務器的同一臺機器上運行,TCP連接數等於代理對象的數量。這意味着所有請求都是並行服務的。這很好。
  • 如果我在一臺單獨的機器上運行服務器,我發現無論創建的代理對象的數量是多少,都會打開最多2個TCP連接。只有兩個請求並行運行。它嚴重傷害了處理速度。
  • 如果我切換到net.tcp綁定,一切正常(每個代理對象的一個​​單獨的TCP連接,即使它們在不同的機器上運行)。

我很困惑,無法讓basicHttpBinding使用更多的TCP連接。我知道這是一個很長的問題,但請幫助!

+0

在配置文件中... – 2010-03-17 10:18:40

回答

9

後在這個問題上花了兩天時間,我找到了解決方案,讓我在這裏記錄它。

實際上問題不是服務配置或限制。實際上,如果客戶端沒有連接到它,服務器(WCF主機)不能做任何事情。在這種情況下,WCF客戶端的連接數不超過2個。我試過basicHttpBinding,WsHttpBinding,甚至是很好的舊web引用(asmx)方法。每個案例都沒有超過2個連接。

此效果的根源在於ServicePointManager.DefaultConnectionLimit屬性,該屬性的默認值爲2.此類位於負責生成Http連接的System.Net名稱空間中。顯然,WCF和ASMX Web引用都使用System.Net命名空間來完成它們的HTTP內容。這解釋了爲什麼即使在多個線程中創建多個代理客戶端後,我也無法提出多個服務請求。

總之,解決方法是將ServicePointManager.DefaultConnectionLimit設置爲您要從客戶端發出的併發呼叫數。

+0

老兄,救命啊! – CtrlDot 2011-09-16 00:18:55

+0

的確是一個救星。 – 2013-01-21 12:56:13

1

退房服務器限制 - 這是你可以應用到你的服務器端配置服務器端的行爲:

<system.serviceModel> 
    <services> 
     <service 
     name="Microsoft.WCF.Documentation.SampleService" 
     behaviorConfiguration="Throttled" > 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://localhost:8080/SampleService"/> 
      </baseAddresses> 
     </host> 
     <endpoint 
      address="" 
      binding="wsHttpBinding" 
      contract="Microsoft.WCF.Documentation.ISampleService" 
     /> 
     <endpoint 
      address="mex" 
      binding="mexHttpBinding" 
      contract="IMetadataExchange" 
     /> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="Throttled"> 
      <serviceThrottling 
      maxConcurrentCalls="1" 
      maxConcurrentSessions="1" 
      maxConcurrentInstances="1" /> 
      <serviceMetadata httpGetEnabled="true" httpGetUrl="" /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 

請參閱本blog post更詳細的信息,或檢查MSDN docs on Service Throttling

+0

我已經添加了示例代碼來詳細說明我的問題。請你幫忙嗎? – Hemant 2010-03-18 07:30:46