Reputation: 357
We have written an application that connects with an external API. You need to have a Token to communicate with this api. The token have to be unique for each user. To obtain a token we need to call an endpoint with a client-certificate that belongs to this user.
We have implemented this by using 1 static HttpClientHandler instance for all API requests. Each request is setting up a HttpClient with this static handler given; and only the client will be disposed, the handler will be kept alive. However to obtain a token; we need to add the certificate to the handler. Therefore when obtaining a token; we uses a new HttpClientHandler instance specific for obtaining the token. As soon the token is obtained, we dispose the client and the handler instance.
Now a lot of calls are failing with the following error:
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond [ip]:443
most of the errors happens when we obtain the Token. But sometimes a normal API call is failing with this same error.
The other party has also researched this issue; and the latest conclusion they gave us: is that at the end of the request we keep the connection alive; so the port is reserved for that connection. However sometimes a new request (new connection I guess) is tried to setup from our side with the same port. There firewall is blocking/dropping this new request; because this port is already in use. And that is why we ends with this time out error.
Well this makes sense; we do not have control over the ports that the connection uses. But why does this happening? I have this theory that the issue lies in the combination of the static handler (that supports 10 parallels connections and keep this connections inactive, but alive) and the second (or more) other handlers that may think that a port is free (because there are not activities on this port) may try to setup a connection with that port. But it is just a theory; i can not find proof for this.
Is there someone that can confirm this theory; or maybe give an other explanation why this issue may appear? And/or is there a solution/workaround for this issue?
Upvotes: 0
Views: 180
Reputation: 933
Ho, I think you're facing a problem called Socket Exhaustion. Although you do dispose()
the HTTP Client, the socket it used will still be reserved for a certain amount of time. To prevent this, you need a mechanism that allows you to re-use the HttpClients and therefore the underlying sockets they use.
The recommended way is to use the HttpClientFactory. This factory will build a pool with HttpClients and provides you with one on-demand while maintaining the pool of clients for you.
More information is found on the Microsoft Docs website: https://learn.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests
Upvotes: 0