[英]How to fix basicHttpBinding in WCF when using multiple proxy clients?
[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: 请考虑以下基本上是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 ();
}
}
}
Also the WCF client program is: 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 ();
}
}
Basically, I am creating 10 proxy clients and then repeatedly calling Add service method on separate threads. 基本上,我正在创建10个代理客户端,然后在不同的线程上重复调用Add service方法。 Now if I run both applications and observe opened TCP connections using netstat, I find that:
现在如果我运行两个应用程序并使用netstat观察打开的TCP连接,我发现:
I am very confused and unable to make the basicHttpBinding use more TCP connections. 我很困惑,无法使basicHttpBinding使用更多的TCP连接。 I know it is a long question, but please help!
我知道这是一个很长的问题,但请帮忙!
After spending 2 days on this problem, I found the solution so let me document it here. 在这个问题上花了2天后,我找到了解决方案,所以让我在这里记录下来。
Actually the problem is not of service configuration or throttling. 实际上问题不在于服务配置或限制。 Actually server (WCF host) cannot do anything if a client is not making connection to it.
实际上,如果客户端没有与它建立连接,服务器(WCF主机)就无法执行任何操作。 In this case WCF client was not making more than 2 connections.
在这种情况下,WCF客户端没有超过2个连接。 I tried basicHttpBinding, WsHttpBinding and even the good old web reference (asmx) method.
我尝试了basicHttpBinding,WsHttpBinding甚至是旧的Web引用(asmx)方法。 Every case failed to make more than 2 connections.
每个案例都没有超过2个连接。
The root of this effect lies in ServicePointManager.DefaultConnectionLimit property which has a default value of 2. This class is in System.Net namespace which is responsible for making Http connections. 此效果的根源在于ServicePointManager.DefaultConnectionLimit属性,其默认值为2.此类位于System.Net命名空间中,该命名空间负责进行Http连接。 Apparently both WCF and ASMX web reference use System.Net namespace for doing their HTTP stuff.
显然,WCF和ASMX Web引用都使用System.Net命名空间来执行HTTP操作。 This explains why I couldn't make multiple service request even after creating multiple proxy clients in multiple threads.
这解释了为什么即使在多个线程中创建多个代理客户端之后我也无法发出多个服务请求。
In summary, the solution is to set ServicePointManager.DefaultConnectionLimit
to the number of concurrent calls you want to make from your client . 总之,解决方案是将
ServicePointManager.DefaultConnectionLimit
设置为您要从客户端进行的并发调用的数量。
Check out server throttling - it's a server-side behavior which you can apply to your server-side config: 检查服务器限制 - 这是一个服务器端行为,您可以将其应用于服务器端配置:
<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>
See this blog post for more detailed info, or check the MSDN docs on Service Throttling 有关更多详细信息,请参阅此博客文章 ,或查看有关服务限制的MSDN文档
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.