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

14,225

Solution 1

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;

Solution 2

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();
}


Share:
14,225
Shahar Prish
Author by

Shahar Prish

Updated on June 09, 2022

Comments

  • Shahar Prish
    Shahar Prish almost 2 years

    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?

  • Shahar Prish
    Shahar Prish about 11 years
    Thanks for the answer Adam... 1. We are not doing POSTs, we are doing GETs and the server verifies that, so we can't switch to post) 2. Why are you doing "as HttpMessageHandler" on your HttpClientHandler? HttpClientHandler is am HttpMessageHandler.
  • Shahar Prish
    Shahar Prish about 11 years
    We tried adding the Keep-Alive header both through DefaultHeaders and through changes in HttpRequestMessage. But we didn't try it directly on the request object. I'll try that, but since the other 2 methods did not put the headers on the request, I don't have high hopes.
  • Adam Tuliper
    Adam Tuliper about 11 years
    I tested the exact code above for the GET request in a winrt app and I get Connection: Keep-Alive as the only request header. 'Works on my machine' : )