2016-08-16 3 views
0

Так у меня есть 2 запросов HTTP Post, потребляющих веб-интерфейс API следующим образом: -C# потреблять веб-апи с несколькими POST HTTP просит

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, который насчитывает 100 запросов на отправку почты для вышеуказанных 2 образцов).

+0

Я считаю, что они есть. Насколько я знаю, они отправляются как разные запросы по той же сессии SSL. Почему бы вам не попробовать примерный сервер? –

+0

Что вы подразумеваете под типовым сервером? – Philo

+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 

и просто улучшение вашего кода: использование попробуйте/поймать, чтобы сделать запросы!

+0

спасибо Forlani. Я проверю асинхронный вызов. Я использую try/catch. Я опубликовал очень упрощенную версию моего кода ... Еще один вопрос, который пришел на ум, мы можем отправить несколько данных запроса, упакованных как один http POST, тогда сервер отвечает отдельные ответы? – Philo

1

Хотя HttpClient будет стремиться использовать тот же сеанс и соединение Ssl, это не может быть гарантировано, так как это зависит от того, сервер также поддерживает сеанс и соединение. Если сервер опустил их, HttpClient будет прозрачно пересматривать новые подключения и сеансы.

Это говорит о том, что, хотя есть некоторые накладные расходы на подключение и создание сеанса ssl, это вряд ли станет основной причиной любых проблем с производительностью.

Учитывая простоту вашего кода выше, я сильно подозреваю, что проблема с производительностью не в вашем клиентском коде, а в службе, к которой вы подключаетесь.

Чтобы определить это, вам необходимо изолировать производительность этой службы. Несколько вариантов, как сделать это, в зависимости от уровня управления вы имеете над этой службой:

  1. Если вы являетесь владельцем этой услуги, осуществлять по тестированию производительности провода непосредственно к службе, используя инструмент как https://www.blitz.io/. Если 100 последовательных запросов от blitz.io занимают 11 секунд, то код, который вы опубликовали, не является виновником, так как сама услуга имеет среднее время отклика 110 мс.
  2. Если вы не являетесь владельцем этой службы, используйте инструмент, например Mountebank, чтобы создать двойную проверку этого соединения и использовать существующий тестовый цикл. Если тестовый цикл с использованием Mountebank выполняется быстро, то опять же код, который вы опубликовали, не является виновником. (Mountebank поддерживает https, но вам нужно либо иметь ключевую пару, либо использовать свой самозаверяющий сертификат, либо отключить проверку сертификата у вашего клиента.)

Следует отметить, что для сложных веб-сервисов нестандартно принимать 110 мс для ответа. Кажется, что ваш тест выполняет последовательную серию запросов - по одному запросу - большинство веб-сервисов оптимизированы для параллельной обработки многих запросов независимых пользователей. Задача масштабируемости заключается в том, сколько одновременных пользователей я могу обслуживать, сохраняя при этом, что среднее время отклика составляет 110 мс. Но если только один пользователь использует услугу за раз, она все равно займет ~ 110 мс.

Итак - еще более ранний шаг проверки, который вы можете предпринять, заключается в том, чтобы выполнить, если ваш тест из 100 последовательных запросов в цикле является действительным представлением ваших фактических требований к производительности, или если вы должны вызвать свой метод 100 раз параллельно с посмотрите, можете ли вы иметь 100 одновременных пользователей для доступа к вашему сервису.

+0

спасибо за ответ. Я не думаю, что я конкретно скажу, что есть проблема с производительностью .. по крайней мере, не то, что я знаю ... однако я хочу улучшить, когда есть место. Есть ли возможность отправить несколько параметров одним запросом? а затем получать отдельные ответы? – Philo

+0

Вы можете [пакетные запросы] (https://blogs.msdn.microsoft.com/webdev/2013/11/01/introducing-batch-support-in-web-api-and-web-api-odata/), но он требует значительных обновлений на стороне сервера. Я думаю, что в вашем случае это будет сложно, потому что для второго вызова API требуются данные ответа от первого. Единственный способ улучшить это дальше - пересмотреть общую архитектуру и дизайн API, чтобы увидеть, действительно ли вам нужно разбить их на два запроса. –

+0

Большое спасибо за информацию. Очень полезно. – Philo

Смежные вопросы