使用HTTPWebRequest请求别人的接口,请求了一次,但是对方却收到了两次同样的请求,而且间隔时间为一分钟,并且只有处理数据比较多的时候才会出现。
因为我自己的代码里是有设置超时时间的,且时间设置的是5分钟, webRequest.Timeout = 300000;
排查了很久,最后发现是因为对方使用的 Nginx自身的机制里面设置了1分钟超时重发导致的,对方进行了接口处理优化,提高速度,并修改了超时时间,问题解决。
以下是我的HTTPWebRequest请求:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using JXLService.Apis.Dto;
namespace JXLService.Utils
{
/// <summary>
/// Http客户端工具类
/// </summary>
/// <typeparam name="TRequest">请求</typeparam>
/// <typeparam name="TResponse">响应</typeparam>
internal class ApiHttpClient<TRequest, TResponse> where TRequest : RequestBase where TResponse : ResponseBase
{
private static readonly string JXLServiceUrl = ConfigurationManager.AppSettings["JXLService"];
/// <summary>
/// 字符编码
/// </summary>
private readonly Encoding _DefaultEncoding = Encoding.UTF8;
/// <summary>
/// 发送请求,获取返回值
/// </summary>
/// <param name="requestData">请求对象</param>
/// <returns></returns>
public TResponse GetResponse(string url, TRequest requestData)
{
//签名
requestData.time = DateTime.Now;
string json = JsonHelper.ObjectToJson(requestData);//完整参数
byte[] bs = _DefaultEncoding.GetBytes(json);
string requsetUrl = JXLServiceUrl + url;
//创建http请求
HttpWebRequest webRequest = CreateHttpWebRequest(requsetUrl);
webRequest.Method = "POST";
webRequest.ContentType = "application/json";
webRequest.ContentLength = bs.Length;
using (Stream reqStream = webRequest.GetRequestStream())
{
reqStream.Write(bs, 0, bs.Length);
}
HttpWebResponse webResponse;
try
{
webRequest.Timeout = 300000;
//获取响应
webResponse = (HttpWebResponse)webRequest.GetResponse();
}
catch (WebException ex)
{
//返回值非200 会有异常
//若服务端在调用不成功时,会修改响应status,需要在这里获取HttpWebResponse
//webResponse = (HttpWebResponse)ex.Response;
throw new ApiException("002", "调用接口错误:" + ex.Status + " " + ex.Message);
}
Stream responseStream = webResponse.GetResponseStream();
if (webResponse.ContentEncoding.ToLower().Contains("gzip"))
{
//gzip格式
responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
}
string responseString = "";
using (StreamReader reader = new StreamReader(responseStream, Encoding.UTF8))
{
responseString = reader.ReadToEnd();
}
if (responseString != null && responseString.Length > 0)
{
TResponse responseObj = JsonHelper.JsonToObject<TResponse>(responseString);
return responseObj;
//if (responseObj.code==0)
//{
// return responseObj;
//}
//else
//{
// throw new ApiException("001", responseObj.msg);
//}
}
else
{
string res = "{"msg":"发薪平台接口错误","code":001}";
TResponse responseObj = JsonHelper.JsonToObject<TResponse>(res);
return responseObj;
//throw new Exception("调用接口错误,没有返回值");
}
}
/// <summary>
/// 创建请求
/// </summary>
/// <param name="url">地址</param>
/// <returns></returns>
private static HttpWebRequest CreateHttpWebRequest(string url)
{
HttpWebRequest request;
//如果是发送HTTPS请求
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
//ServicePointManager.DefaultConnectionLimit = 1000;
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
request = WebRequest.Create(url) as HttpWebRequest;
request.ProtocolVersion = HttpVersion.Version11;
}
else
{
request = WebRequest.Create(url) as HttpWebRequest;
}
request.Proxy = null;
request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");//若支持压缩 注意需要给在获取响应时解压
return request;
}
/// <summary>
/// https 校验证书
/// </summary>
/// <param name="sender"></param>
/// <param name="certificate"></param>
/// <param name="chain"></param>
/// <param name="errors"></param>
/// <returns></returns>
private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
//todo 验证对方证书
return true; //总是接受
}
}
}