zoukankan      html  css  js  c++  java
  • .net的 http 请求 利用单例减少创建销毁的资源开销 提高利用率

    参照腾讯云sdk  链接  https://github.com/TencentCloud/tencentcloud-sdk-dotnet/blob/master/TencentCloud/Common/Http/HttpConnection.cs

    减小创建的开销可以用单例,也可以用请求池,后续再简单写个请求池,这次主要贴下腾讯的代码,照着腾讯sdk的请求方式 可以直接搬到自己的项目中去使用 代码就不一一解释了,很容易看明白

    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Net;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace TencentCloud.Common.Http
    {
        public class HttpConnection
        {
            private class HttpClientHolder
            {
                private static readonly ConcurrentDictionary<string, HttpClientHolder> httpclients = new ConcurrentDictionary<string, HttpClientHolder>();
    
                public static HttpClient GetClient(string proxy)
                {
                    string key = string.IsNullOrEmpty(proxy) ? "" : proxy;
                    HttpClientHolder result = httpclients.GetOrAdd(key, (k) =>
                    {
                        return new HttpClientHolder(k);
                    });
                    TimeSpan timeSpan = DateTime.Now - result.createTime;
    
                    // 每5分钟创建一个新的连接,放弃旧连接,避免DNS刷新问题。
                    while (timeSpan.TotalSeconds > 300)
                    {
                        ICollection<KeyValuePair<string, HttpClientHolder>> kv = httpclients;
                        kv.Remove(new KeyValuePair<string, HttpClientHolder>(key, result));
                        result = httpclients.GetOrAdd(key, (k) =>
                        {
                            return new HttpClientHolder(k);
                        });
                        timeSpan = DateTime.Now - result.createTime;
                    }
                    return result.client;
                }
    
                public readonly HttpClient client;
    
                public readonly DateTime createTime;
    
                public HttpClientHolder(string proxy)
                {
                    string p = string.IsNullOrEmpty(proxy) ? "" : proxy;
                    if (p == "")
                    {
                        this.client = new HttpClient();
                    }
                    else
                    {
                        var httpClientHandler = new HttpClientHandler
                        {
                            Proxy = new WebProxy(proxy),
                        };
    
                        this.client = new HttpClient(handler: httpClientHandler, disposeHandler: true);
                    }
                    this.client.Timeout = TimeSpan.FromSeconds(60);
                    this.createTime = DateTime.Now;
                }
            }
    
            private readonly HttpClient http;
    
            private readonly string baseUrl;
    
            private readonly string proxy;
    
            private readonly int timeout;
    
            public HttpConnection(string baseUrl, int timeout, string proxy, HttpClient http)
            {
                this.proxy = string.IsNullOrEmpty(proxy) ? "" : proxy;
                this.timeout = timeout;
                this.baseUrl = baseUrl;
                if (http != null)
                {
                    this.http = http;
                }
                else
                {
                    this.http = HttpClientHolder.GetClient(this.proxy);
                }
            }
    
            private static string AppendQuery(StringBuilder builder, Dictionary<string, string> param)
            {
                foreach (KeyValuePair<string, string> kvp in param)
                {
                    builder.Append($"{WebUtility.UrlEncode(kvp.Key)}={WebUtility.UrlEncode(kvp.Value)}&");
                }
                return builder.ToString().TrimEnd('&');
            }
    
            public async Task<HttpResponseMessage> GetRequestAsync(string url, Dictionary<string, string> param)
            {
                StringBuilder urlBuilder = new StringBuilder($"{baseUrl.TrimEnd('/')}{url}?");
                string fullurl = AppendQuery(urlBuilder, param);
                string payload = "";
                Dictionary<string, string> headers = new Dictionary<string, string>();
                return await this.Send(HttpMethod.Get, fullurl, payload, headers);
            }
    
            public async Task<HttpResponseMessage> GetRequestAsync(string path, string queryString, Dictionary<string, string> headers)
            {
                string fullurl = $"{this.baseUrl.TrimEnd('/')}{path}?{queryString}";
                string payload = "";
                return await this.Send(HttpMethod.Get, fullurl, payload, headers);
            }
    
            public async Task<HttpResponseMessage> PostRequestAsync(string path, string payload, Dictionary<string, string> headers)
            {
                string fullurl = $"{baseUrl.TrimEnd('/')}{path}";
                return await this.Send(HttpMethod.Post, fullurl, payload, headers);
            }
    
            public async Task<HttpResponseMessage> PostRequestAsync(string url, Dictionary<string, string> param)
            {
                string fullurl = $"{this.baseUrl.TrimEnd('/')}{url}?";
                StringBuilder payloadBuilder = new StringBuilder();
                string payload = AppendQuery(payloadBuilder, param);
                Dictionary<string, string> headers = new Dictionary<string, string>();
                headers["Content-Type"] = "application/x-www-form-urlencoded";
                return await this.Send(HttpMethod.Post, fullurl, payload, headers);
            }
    
            private async Task<HttpResponseMessage> Send(HttpMethod method, string url, string payload, Dictionary<string, string> headers)
            {
                using (var cts = new System.Threading.CancellationTokenSource(timeout * 1000))
                {
                    using (var msg = new HttpRequestMessage(method, url))
                    {
                        foreach (KeyValuePair<string, string> kvp in headers)
                        {
                            if (kvp.Key.Equals("Content-Type"))
                            {
                                msg.Content = new StringContent(payload, Encoding.UTF8, kvp.Value);
                            }
                            else if (kvp.Key.Equals("Host"))
                            {
                                msg.Headers.Host = kvp.Value;
                            }
                            else if (kvp.Key.Equals("Authorization"))
                            {
                                msg.Headers.Authorization = new AuthenticationHeaderValue("TC3-HMAC-SHA256", kvp.Value.Substring("TC3-HMAC-SHA256".Length));
                            }
                            else
                            {
                                msg.Headers.Add(kvp.Key, kvp.Value);
                            }
                        }
                        return await http.SendAsync(msg, cts.Token);
                    }
                }
            }
        }
    }
    

      

    /*
      * Copyright (c) 2018 THL A29 Limited, a Tencent company. All Rights Reserved.
      *
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
      *
      * http://www.apache.org/licenses/LICENSE-2.0
      *
      * Unless required by applicable law or agreed to in writing,
      * software distributed under the License is distributed on an
      * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
      * KIND, either express or implied. See the License for the
      * specific language governing permissions and limitations
      * under the License.
      */
      using System;
      using System.Collections.Concurrent;
      using System.Collections.Generic;
      using System.Net;
      using System.Net.Http;
      using System.Net.Http.Headers;
      using System.Text;
      using System.Threading.Tasks;
       
      namespace TencentCloud.Common.Http
      {
      public class HttpConnection
      {
      private class HttpClientHolder
      {
      private static readonly ConcurrentDictionary<string, HttpClientHolder> httpclients = new ConcurrentDictionary<string, HttpClientHolder>();
       
      public static HttpClient GetClient(string proxy)
      {
      string key = string.IsNullOrEmpty(proxy) ? "" : proxy;
      HttpClientHolder result = httpclients.GetOrAdd(key, (k) =>
      {
      return new HttpClientHolder(k);
      });
      TimeSpan timeSpan = DateTime.Now - result.createTime;
       
      // 每5分钟创建一个新的连接,放弃旧连接,避免DNS刷新问题。
      while (timeSpan.TotalSeconds > 300)
      {
      ICollection<KeyValuePair<string, HttpClientHolder>> kv = httpclients;
      kv.Remove(new KeyValuePair<string, HttpClientHolder>(key, result));
      result = httpclients.GetOrAdd(key, (k) =>
      {
      return new HttpClientHolder(k);
      });
      timeSpan = DateTime.Now - result.createTime;
      }
      return result.client;
      }
       
      public readonly HttpClient client;
       
      public readonly DateTime createTime;
       
      public HttpClientHolder(string proxy)
      {
      string p = string.IsNullOrEmpty(proxy) ? "" : proxy;
      if (p == "")
      {
      this.client = new HttpClient();
      }
      else
      {
      var httpClientHandler = new HttpClientHandler
      {
      Proxy = new WebProxy(proxy),
      };
       
      this.client = new HttpClient(handler: httpClientHandler, disposeHandler: true);
      }
      this.client.Timeout = TimeSpan.FromSeconds(60);
      this.createTime = DateTime.Now;
      }
      }
       
      private readonly HttpClient http;
       
      private readonly string baseUrl;
       
      private readonly string proxy;
       
      private readonly int timeout;
       
      public HttpConnection(string baseUrl, int timeout, string proxy, HttpClient http)
      {
      this.proxy = string.IsNullOrEmpty(proxy) ? "" : proxy;
      this.timeout = timeout;
      this.baseUrl = baseUrl;
      if (http != null)
      {
      this.http = http;
      }
      else
      {
      this.http = HttpClientHolder.GetClient(this.proxy);
      }
      }
       
      private static string AppendQuery(StringBuilder builder, Dictionary<string, string> param)
      {
      foreach (KeyValuePair<string, string> kvp in param)
      {
      builder.Append($"{WebUtility.UrlEncode(kvp.Key)}={WebUtility.UrlEncode(kvp.Value)}&");
      }
      return builder.ToString().TrimEnd('&');
      }
       
      public async Task<HttpResponseMessage> GetRequestAsync(string url, Dictionary<string, string> param)
      {
      StringBuilder urlBuilder = new StringBuilder($"{baseUrl.TrimEnd('/')}{url}?");
      string fullurl = AppendQuery(urlBuilder, param);
      string payload = "";
      Dictionary<string, string> headers = new Dictionary<string, string>();
      return await this.Send(HttpMethod.Get, fullurl, payload, headers);
      }
       
      public async Task<HttpResponseMessage> GetRequestAsync(string path, string queryString, Dictionary<string, string> headers)
      {
      string fullurl = $"{this.baseUrl.TrimEnd('/')}{path}?{queryString}";
      string payload = "";
      return await this.Send(HttpMethod.Get, fullurl, payload, headers);
      }
       
      public async Task<HttpResponseMessage> PostRequestAsync(string path, string payload, Dictionary<string, string> headers)
      {
      string fullurl = $"{baseUrl.TrimEnd('/')}{path}";
      return await this.Send(HttpMethod.Post, fullurl, payload, headers);
      }
       
      public async Task<HttpResponseMessage> PostRequestAsync(string url, Dictionary<string, string> param)
      {
      string fullurl = $"{this.baseUrl.TrimEnd('/')}{url}?";
      StringBuilder payloadBuilder = new StringBuilder();
      string payload = AppendQuery(payloadBuilder, param);
      Dictionary<string, string> headers = new Dictionary<string, string>();
      headers["Content-Type"] = "application/x-www-form-urlencoded";
      return await this.Send(HttpMethod.Post, fullurl, payload, headers);
      }
       
      private async Task<HttpResponseMessage> Send(HttpMethod method, string url, string payload, Dictionary<string, string> headers)
      {
      using (var cts = new System.Threading.CancellationTokenSource(timeout * 1000))
      {
      using (var msg = new HttpRequestMessage(method, url))
      {
      foreach (KeyValuePair<string, string> kvp in headers)
      {
      if (kvp.Key.Equals("Content-Type"))
      {
      msg.Content = new StringContent(payload, Encoding.UTF8, kvp.Value);
      }
      else if (kvp.Key.Equals("Host"))
      {
      msg.Headers.Host = kvp.Value;
      }
      else if (kvp.Key.Equals("Authorization"))
      {
      msg.Headers.Authorization = new AuthenticationHeaderValue("TC3-HMAC-SHA256", kvp.Value.Substring("TC3-HMAC-SHA256".Length));
      }
      else
      {
      msg.Headers.Add(kvp.Key, kvp.Value);
      }
      }
      return await http.SendAsync(msg, cts.Token);
      }
      }
      }
      }
      }
  • 相关阅读:
    路由器欺骗(原始套接字五)
    ICMP拒绝服务攻击(原始套接字系列四)
    ping的实现(原始套接字系列三)
    原始套接字基础(原始套接字系列二)
    原始套接字简介(原始套接字系列一)
    MMS服务学习
    转 Qt 翻译
    为应用程序设置一个图标 (窗口左上角 程序图标)
    正则表达式
    《TCP/IP详解 卷1:协议》第4章 ARP:地址解析协议
  • 原文地址:https://www.cnblogs.com/mintworld/p/13905439.html
Copyright © 2011-2022 走看看