C#使用带有多个http POST请求的web api

时间:2016-08-16 18:33:43

标签: c# session asp.net-web-api

所以我有2个http Post请求使用web api,如下所示: -

using (var client = new HttpClient())
{
   client.BaseAddress = new Uri("https://your_url.com:8443/");
   client.DefaultRequestHeaders.Accept.Clear();
   client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

   // 1st request //
   var datatobeSent = new ApiSendData()
    {
        UserID = "xxx",
        UserPsw = "yyy",
        ApiFunc = "zzz",
        clearData = "x1y1z1"
    };

    HttpResponseMessage response = await client.PostAsJsonAsync("WebApi", datatobeSent);
    var resultData = await response.Content.ReadAsStringAsync();


   #region Extract Secured Data response from WebApi

   JObject JsonObject = JObject.Parse(resultData);
   datatobeSent.SecureData = (string)JsonObject["SecureResult"];

   #endregion


   // 2nd request //
   var datatobeSent2 = new ApiSendData()
   {
     UserID = "xxx",
     UserPsw = "yyy",
     ApiFunc = "zzz",
     SecureData = datatobeSent.SecureData
   };

   HttpResponseMessage response2 = await client.PostAsJsonAsync("WebApi", datatobeSent2);
   var resultData2 = await response2.Content.ReadAsStringAsync();

}

所以现在我需要一些澄清......

1)我的http POST请求是否都通过同一个SSL会话发送?

2)如果不是,那么如何将两者结合起来并通过单个连接/会话发送2个请求?

3)如何提高此代码的性能?目前有100个请求需要11个来处理和响应。 (我只使用了一个for循环,对上述2个样本计算了100个http post请求)

2 个答案:

答案 0 :(得分:1)

它们位于相同的SSL会话和连接上。相同的HttpClient实例共享一些配置和底层TCP连接。因此,您应该重用与using语句已经使用的相同的实例。

我会尝试通过异步发布帖子请求和处理结果来提高代码的性能。这是一个选项:

创建一个新类来处理这些异步请求

public class WebHelper
{
   public async Task<string> MakePostRequest(HttpClient client, string route, object dataToBeSent)
   {
      try{
            HttpResponseMessage response = await client.PostAsJsonAsync(route, datatobeSent);
            string resultData = await response.Content.ReadAsStringAsync();
            return resultData;
      }
      catch (Exception ex){
         return ex.Message;
    }
  }
}

请注意,正在使用相同的httpClient实例。在主代码中,您可以像这样测试您的性能(为了简化我们的测试,我只是使用相同的参数101次发布请求):

//Start time measurement
List<Task> TaskList = new List<Task>();
for (int i = 0; i < 100; i++)
{
  Task postTask = Task.Run(async () =>
  {
     WebHelper webRequest = new WebHelper();
     string response = await webRequest.MakePostRequest(client, "WebApi", dataToBeSent);
     Console.WriteLine(response);
  });
  TaskList.Add(postTask);
}
Task.WaitAll(TaskList.ToArray());
//end time measurement

只是对您的代码进行了改进:使用try / catches来发出请求!

答案 1 :(得分:1)

虽然HttpClient的目标是使用相同的Ssl会话和连接,但这不能保证,因为它依赖于服务器还维护会话和连接。如果服务器丢弃它们,HttpClient将透明地重新协商新的连接和会话。

尽管如此,虽然连接和ssl会话建立有一些开销,但它不太可能是任何性能问题的根本原因。

鉴于上述代码的简单性,我强烈怀疑性能问题不在您的客户端代码中,而是在您要连接的服务中。

要确定这一点,您需要隔离该服务的性能。有关如何执行此操作的一些选项,具体取决于您对该服务的控制级别:

  1. 如果您是该服务的所有者,请使用https://www.blitz.io/之类的工具直接针对该服务执行电线性能测试。如果来自blitz.io的100个连续请求需要11秒,那么您发布的代码不是罪魁祸首,因为服务本身的平均响应时间为110毫秒。
  2. 如果您不是该服务的所有者,请使用Mountebank之类的工具创建该服务的双线测试,并使用现有的测试循环。如果使用Mountebank的测试循环快速执行,那么您发布的代码不是罪魁祸首。 (Mountebank支持https,但您需要拥有密钥对,或使用自签名证书并在您的客户端禁用证书验证。)
  3. 值得注意的是,复杂的Web服务需要110毫秒才能响应。您的测试似乎正在执行一系列连续的请求 - 一次一个请求 - 大多数Web服务都是围绕独立处理来自独立用户的请求进行优化的。可扩展性的挑战在于我可以服务多少并发用户,同时仍然确保平均响应时间为110毫秒。但如果一次只有一个用户使用该服务,它仍然需要~1.1ms。

    所以 - 你可以采取的更早的验证步骤是,如果你在循环中对100个连续请求的测试是你实际性能要求的有效表示,或者你应该并行调用你的方法100次看看如果您有100个并发用户可以访问您的服务。