Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a Keep-Alive connection in WinRT's HttpClient class?

Our WinRT app is incredibly slow when opening connections to our servers. Requests take ~500ms to run. This is blocking some of our scenarios.

When debugging, we noticed that when Fiddler is active, the requests are much faster - ~100ms per request. Some searches later we understood that was because Fiddler was using Keep-Alive connections when proxying calls, which makes our proxied calls much faster.

We double-checked this in two ways.

  1. We set UseProxy to false and observed that the request went back to being slow.
  2. We turned off Fiddler's "reuse connections" option and observed that the requests went back to being slow.

We tried enabling keep-alive through the Connection header (.Connection.Add("Keep-Alive")) but this does not seem to have any effect - in fact, the header seems to be blatantly ignored by the .NET component and is not being sent on the request (again, by inspecting thru Fiddler).

Does anyone know how to set keep-alive on requests in Windows 8, WinRT, HttpClient class?

like image 546
Shahar Prish Avatar asked Mar 04 '13 21:03

Shahar Prish


People also ask

How do I keep my HTTP connection alive?

The default HTTP connection is usually closed after each request has been completed, meaning that the server closes the TCP connection after delivering the response. In order to keep the connection open for multiple requests, the keep-alive connection header can be used.

Does https have Keep-Alive?

HTTP keep-alive, a.k.a., HTTP persistent connection, is an instruction that allows a single TCP connection to remain open for multiple HTTP requests/responses. By default, HTTP connections close after each request.

What is http keep alive timeout?

The keep alive timeout on the Message Processor allows a single TCP connection to send and receive multiple HTTP requests/responses from/to the backend server, instead of opening a new connection for every request/response pair.

How do you make a Keep-Alive header?

The user must set the Connection HTTP Header to Keep-Alive HTTP Header if the user wants the keep-alive header to have any effect. The Connection general header determines whether or not the network connection will be kept open after the current transaction has been successfully completed.


2 Answers

The following sets the correct headers to turn on keep-alive for me (client is an HttpClient)

client.DefaultRequestHeaders.Connection.Clear();
client.DefaultRequestHeaders.ConnectionClose = false;
// The next line isn't needed in HTTP/1.1
client.DefaultRequestHeaders.Connection.Add("Keep-Alive");

If you want to turn keep-alive off, use

client.DefaultRequestHeaders.Connection.Clear();
client.DefaultRequestHeaders.ConnectionClose = true;
like image 72
Adam Avatar answered Sep 28 '22 14:09

Adam


Try using the HttpContent class to add the headers - something like this based on (but untested) http://social.msdn.microsoft.com/Forums/en-CA/winappswithcsharp/thread/ce2563d1-cd96-4380-ad41-6b0257164130

Behind the scenes HttpClient uses HttpWebRequest which would give you direct access to KeepAlive but since you are going through HttpClient you can't directly access that property on the HttpWebRequest class.


public static async Task KeepAliveRequest()
{
    var handler = new HttpClientHandler();
    var client = new HttpClient(handler as HttpMessageHandler);

    HttpContent content = new StringContent(post data here if doing a post);
    content.Headers.Add("Keep-Alive", "true");

    //choose your type depending what you are sending to the server
    content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");

    HttpResponseMessage response = await client.PostAsync(url, content);

    Stream stream = await response.Content.ReadAsStreamAsync();

    return new StreamReader(stream).ReadToEnd();
}


EDIT Since you only want GET, you can do that with:


public static async Task KeepAliveRequest(string url)
{
    var client = new HttpClient();
    var request = new HttpRequestMessage()
    {
        RequestUri = new Uri("http://www.bing.com"),
        Method = HttpMethod.Get,
    };
    request.Headers.Add("Connection", new string[] { "Keep-Alive" });
    var responseMessage = await client.SendAsync(request);
    return await responseMessage.Content.ReadAsStringAsync();
}


like image 24
Adam Tuliper Avatar answered Sep 28 '22 16:09

Adam Tuliper