11#if NET45
22
3+ using System . Collections . Generic ;
34using System . Net ;
45using System . Net . Http ;
56using System . Threading ;
7+ using System ;
8+ using System . Text ;
69using System . Threading . Tasks ;
710
811namespace WebApiClient
@@ -18,20 +21,24 @@ class DefaultHttpClientHandler : WebRequestHandler
1821 private int sendTimes = 0 ;
1922
2023 /// <summary>
21- /// 最大连接数设置器
24+ /// 站点地址
2225 /// </summary>
23- private static readonly PropertySetter MaxConnectionsPerServer ;
26+ private readonly HashSet < Uri > hashSet = new HashSet < Uri > ( new UriComparer ( ) ) ;
27+
28+ /// <summary>
29+ /// 每个服务的最大连接数设置器
30+ /// </summary>
31+ private static readonly PropertySetter maxConnectionsPerServerSetter ;
2432
2533 /// <summary>
2634 /// 静态构造器
2735 /// </summary>
2836 static DefaultHttpClientHandler ( )
2937 {
30- // 支持st20的framework具有MaxConnectionsPerServer属性
3138 var property = typeof ( HttpClientHandler ) . GetProperty ( "MaxConnectionsPerServer" , typeof ( int ) ) ;
3239 if ( property != null )
3340 {
34- MaxConnectionsPerServer = new PropertySetter ( property ) ;
41+ maxConnectionsPerServerSetter = new PropertySetter ( property ) ;
3542 }
3643 }
3744
@@ -44,13 +51,9 @@ public DefaultHttpClientHandler()
4451 this . Proxy = null ;
4552 this . ServerCertificateValidationCallback = ( a , b , c , d ) => true ;
4653
47- if ( MaxConnectionsPerServer != null )
54+ if ( maxConnectionsPerServerSetter != null )
4855 {
49- MaxConnectionsPerServer . Invoke ( this , HttpApiClient . ConnectionLimit ) ;
50- }
51- else
52- {
53- ServicePointManager . DefaultConnectionLimit = HttpApiClient . ConnectionLimit ;
56+ maxConnectionsPerServerSetter . Invoke ( this , HttpApiClient . ConnectionLimit ) ;
5457 }
5558 }
5659
@@ -62,6 +65,12 @@ public DefaultHttpClientHandler()
6265 /// <returns></returns>
6366 protected override Task < HttpResponseMessage > SendAsync ( HttpRequestMessage request , CancellationToken cancellationToken )
6467 {
68+ // 通过ServicePoint设置最大连接数
69+ if ( maxConnectionsPerServerSetter == null )
70+ {
71+ this . SetServicePointConnectionLimit ( request . RequestUri , HttpApiClient . ConnectionLimit ) ;
72+ }
73+
6574 var header = request . Headers ;
6675 var isClose = header . ConnectionClose == true || header . Connection . Contains ( "close" ) ;
6776
@@ -75,6 +84,43 @@ protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage reques
7584 }
7685 return base . SendAsync ( request , cancellationToken ) ;
7786 }
87+
88+ /// <summary>
89+ /// 通过ServicePoint设置最大连接数
90+ /// 如果其它实例也操作ServicePoint,将影响到本实例
91+ /// 每个站点只设置一次
92+ /// </summary>
93+ /// <param name="address">站点地址</param>
94+ /// <param name="limit">最大连接数</param>
95+ private void SetServicePointConnectionLimit ( Uri address , int limit )
96+ {
97+ if ( this . Proxy != null )
98+ {
99+ address = this . Proxy . GetProxy ( address ) ;
100+ }
101+
102+ if ( this . hashSet . Add ( address ) == true )
103+ {
104+ var point = ServicePointManager . FindServicePoint ( address ) ;
105+ point . ConnectionLimit = limit ;
106+ }
107+ }
108+
109+ /// <summary>
110+ /// Uri比较器
111+ /// </summary>
112+ private class UriComparer : IEqualityComparer < Uri >
113+ {
114+ public bool Equals ( Uri x , Uri y )
115+ {
116+ return true ;
117+ }
118+
119+ public int GetHashCode ( Uri obj )
120+ {
121+ return obj . Scheme . GetHashCode ( ) ^ obj . Authority . GetHashCode ( ) ;
122+ }
123+ }
78124 }
79125}
80126
0 commit comments