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.
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?
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.
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.
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.
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.
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;
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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With