Based on this article I decided to create single instance for my HttpClient
in my project, where are sent two requests to my WebAPI from its consumer. Also to kill the connection aftrewards I decided to use solution from this article. After sending two requests using the singleton I was receiving this exception:
System.InvalidOperationException: This instance has already started one or more requests.
So I decided to use the interface and configuration (similar) from this SO answer. Everything seems to work fine, BUT after running netstat.exe I noticed, that for my API consumer are opened two (2) different connection with various port numbers:
Note that [::1]:49153
is my WebAPI port, so I assume that [::1]:57612
and [::1]:57614
are opened for my consumer. Why? If they supposed to use the same client?
Should not it be like in the first mentioned article?
My HttpClientFactory:
public interface IHttpClientFactory
{
HttpClient CreateClient();
}
public class HttpClientFactory : IHttpClientFactory
{
static AppConfig config = new AppConfig();
static string baseAddress = config.ConnectionAPI;
public HttpClient CreateClient()
{
var client = new HttpClient();
SetupClientDefaults(client);
return client;
}
protected virtual void SetupClientDefaults(HttpClient client)
{
//client.Timeout = TimeSpan.FromSeconds(30);
client.BaseAddress = new Uri(baseAddress);
client.DefaultRequestHeaders.ConnectionClose = true;
}
}
And my two request sending methods:
public async Task<bool> SendPostRequestAsync(string serializedData)
{
CallerName = _messageService.GetCallerName();
HttpResponseMessage response = new HttpResponseMessage();
Console.Write(MessagesInfo[CallerName]);
try
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, Config.ApiPostUri);
request.Content = new StringContent(serializedData, Encoding.UTF8, "application/json");
response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
if (response.IsSuccessStatusCode)
{
Console.WriteLine(MessagesResult[CallerName]); //success status
return true;
}
else
{
throw new Exception("Status code: " + response.StatusCode.ToString());
}
}
catch (Exception e)
{
_logger.Error(e.Message.ToString() + ", " + MessagesError[CallerName]);
CloseConnection();
return false;
}
}
and
public async Task<bool> SendGetRequestAsync()
{
CallerName = _messageService.GetCallerName();
HttpResponseMessage response = new HttpResponseMessage();
Console.Write(MessagesInfo[CallerName]);
try
{
response = await _httpClient.GetAsync(Config.ApiGetUri, HttpCompletionOption.ResponseHeadersRead);
if (response.IsSuccessStatusCode)
{
Console.WriteLine(MessagesResult[CallerName]); //success status
return true;
}
else
{
throw new Exception("Status code: " + response.StatusCode.ToString());
}
}
catch (Exception e)
{
_logger.Error(e.Message.ToString() + ", " + MessagesError[CallerName]);
CloseConnection();
return false;
}
}
Connection is closed with:
public void CloseConnection()
{
CallerName = _messageService.GetCallerName();
var sp = ServicePointManager.FindServicePoint(new Uri(Config.ConnectionAPI));
sp.ConnectionLeaseTimeout = 1 * 1000;
Console.WriteLine();
Console.WriteLine(MessagesResult[CallerName]);
}