参照腾讯云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 | |||
* | |||
* > | * | ||
* 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); | |||
} | |||
} | |||
} | |||
} | |||
} |
原文转载:http://www.shaoqun.com/a/485817.html
香港会计师事务所:https://www.ikjzd.com/w/2434
worldfirst:https://www.ikjzd.com/w/289
黄远:https://www.ikjzd.com/w/1785
参照腾讯云sdk链接https://github.com/TencentCloud/tencentcloud-sdk-dotnet/blob/master/TencentCloud/Common/Http/HttpConnection.cs减小创建的开销可以用单例,也可以用请求池,后续再简单写个请求池,这次主要贴下腾讯的代码,照着腾讯sdk的请求方式可以直接搬到自己的项目中去使用代码就不一一解释了
usps国际快递查询:https://www.ikjzd.com/w/513
trax:https://www.ikjzd.com/w/1489
美国站如何注册?2018年亚马逊美国站注册新变化及流程揭秘!:https://www.ikjzd.com/home/1660
30天学会开店:从零开始了解shopify之Facebook广告创意制作--Day20:https://www.ikjzd.com/home/108453
手把手教你如何通过产品介绍来提高亚马逊上的月销量!:https://www.ikjzd.com/home/124507
No comments:
Post a Comment