У меня есть служба приложений, которая вызывает другого через http-вызовы. При тестировании нашей службы приложений мы выяснили, что фабрика http-клиентов, реализованная в нашем приложении, вызывает исключение Socket при рабочей нагрузке.
После нашего исследования мы обнаружили, что для каждого запроса существует новый порт который открывается без повторного использования уже доступных открытых портов.
Пожалуйста, найдите текущую реализацию нашего HttpClientFactory - Typed Client:
API, который я создал для тестирования:
[HttpGet("/api/RunFirstTest()")]
public void RunFirstTest(int courseId, int learnerId)
{
for (int i = 0; i < 10; i++)
{
CourseSummarySM courseSummarySM = _courseSummaryService.GetCourseSummary(this.Token, courseId, learnerId);
}
}
DependencyInjection:
public static IServiceCollection RegisterGateWayServer(
this IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
// register http call services
services.AddHttpClient<IHttpCallService, HttpCallService>();
services.AddTransient<IDefaultApiCalls, GateWayApiCalls>();
return services;
}
Класс HttpCall:
public class HttpCallService : IHttpCallService
{
private readonly HttpClient _client;
public HttpCallService(HttpClient client)
{
_client = client;
}
private HttpResponseMessage AuthorizedCall(HttpMethod verb, ApiModel model)
{
try
{
HttpRequestMessage request = new HttpRequestMessage(verb, model.url);
if (model.data != null)
{
string jsonstring = JsonConvert.SerializeObject(model.data);//new JavaScriptSerializer().Serialize(model.data);
if (verb.Method == HttpMethod.Post.Method || verb.Method == HttpMethod.Put.Method || verb.Method.Equals("patch", StringComparison.CurrentCultureIgnoreCase))
{
request.Content = new StringContent(jsonstring, Encoding.UTF8, "application/json");
}
}
_client.DefaultRequestHeaders.Clear();
//add custom headers
foreach (var kvp in model.headers)
_client.DefaultRequestHeaders.Add(kvp.Key, kvp.Value.ToString());
Task<HttpResponseMessage> X = _client.SendAsync(request);
X.Wait();
return X.Result;
}
catch (Exception e)
{
}
finally
{
//if (_client != null)
// _client.Dispose();
}
}
Также обратите внимание, что мы используем шаблон репозитория, поэтому курс Сводная служба будет использовать хранилище для выполнения своих http-вызовов