Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use persistent connections with System.Net.Http.HttpClient?

I have created REST resource using Web API running as a self-hosted process. For performance reasons I would like to be able to call it using persistent HTTP connections. I using OWIN self-hosting.

I really like the asnyc methods for GET, POST, PUT, DELETE in System.Net.Http.HttpClient. They are easy to call and deal with--they return a System.Threading.Tasks.Task which is convenient for what I'm trying to do. I prefer using HttpClient to System.Net.HttpWebRequest.

I'm probably missing something, but it isn't readily apparent to me how to create persistent connections with HttpClient. I'm digging through the System.Net.Http.HttpClientHandler and System.Net.Http.WebRequestHandler classes, but so far I haven't found an option for persistent connections. Google finds all sorts of examples of creating persistent connections using HttpWebRequest. It has a KeepAlive property that can be set to true. Is there a way to set this with HttpClient?

MSDN documentation for HttpClient:

By default, HttpWebRequest will be used to send requests to the server. This behavior can be modified by specifying a different channel in one of the constructor overloads taking a HttpMessageHandler instance as parameter. If features like authentication or caching are required, WebRequestHandler can be used to configure settings and the instance can be passed to the constructor. The returned handler can be passed to one of the constructor overloads taking a HttpMessageHandler parameter.

Is there a way to set the KeepAlive feature on the underlying HttpWebRequest?

The MSDN documentation also says:

The HttpClient class instance acts as a session to send HTTP requests. An HttpClient instance is a collection of settings applied to all requests executed by that instance. In addition, every HttpClient instance uses its own connection pool, isolating its requests from requests executed by other HttpClient instances.

Am I to understand from this that the connection pool will optimize for me using persistent connections when a performance benefit can be gained? What if I want there to only ever be a single connection from my client?

like image 515
petrsnd Avatar asked Aug 27 '13 18:08

petrsnd


2 Answers

You will need to set the MaxIdle time on the ServicePoint for the client. The easiest way is to set the timeout for all service points:

ServicePointManager.MaxServicePointIdleTime = Timeout.Infinite;

You can also set it on the connection to the specific endpoint

var sp = ServicePointManager.FindServicePoint(targetUri);
sp.MasIdleTime = Timeout.Infinite;
like image 61
Cody Barnes Avatar answered Sep 20 '22 14:09

Cody Barnes


I'm not sure what exactly you are trying to solve but have you looked at SignalR ? They have pretty fancy websocket api's that might do the job you are looking for.

If you are not using .NET 4.5 then they do have alternate mechanisms. One I'v seen being used is something like a server/event-stream.

like image 28
Developer Avatar answered Sep 18 '22 14:09

Developer