4

In a Xamarin.Forms application I try to connect to the Exosites api (which is not part of the project so I can't change that one so SignalR or so).

It all works fine for "normal" requests.

The api also supports long polling requests - in the manual it says that the client has to set the header "Request-Timeout" to the request.

var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
request.Headers.Add("Request-Timeout", "10000");
var response = await client.SendAsync(request);

But doing so, I don't get any answer back, even if i set the timeout to a very small value like 1 (ms). If I set a timeout on a request to another endpoint on Exosites which does not check on it it works fine. Sending the exact same request without the "Request-Timeout" header also works fine.

Does anyone have experience with long polling calls in Xamarin using HttpClient?

Thanks a lot!

tschuege

tschuege
  • 761
  • 1
  • 8
  • 20

2 Answers2

8

Actually, it's a lot easier than that.

using (var client = new HttpClient())
{
    client.Timeout = TimeSpan.FromSeconds(_timeoutSeconds);
}

PS: Be sure to always wrap your new HttpClient() in a using block.

Chase Florell
  • 46,378
  • 57
  • 186
  • 376
  • Thanks. As I understand it client.Timeout is something different - something HttpClient internal. I see it is a timer that starts when sending the request and if it runs out before the request returns the caller gets notified. The server does participate on that. The header "Request-Timeout" on the other hand is sent to the server. In the Exosites case the server does then not answer immediately and waits until something changes or the time runs out. I tried it with client.Timeout and got an answer immediately even though there were no changes - so it was no long poll. – tschuege Jan 07 '16 at 09:05
  • 4
    It's not good reason to dispose every time HttpClient. It's common mistake a lot of people http://stackoverflow.com/questions/15705092/do-httpclient-and-httpclienthandler-have-to-be-disposed – nick shp Feb 15 '16 at 12:08
2

I finally figured out that "Request-Timeout" is not a standard header. It's a custom header Exosite uses to distinguish long polls from normal calls.

The problem I had was not related to that. I used fiddler to capture a long poll to the Exosite api made using postman. After the time defined with "Request-Timeout" passed by the response returned and Fiddler showed the following protocol violation:

Content-Length mismatch: Response Header indicated 27 bytes, but server sent 0 bytes.

So the problem was that HttpClient was not able to process the response. Fortunately SendAsync has an overload accepting an additional parameter of type HttpCompletionOption that has the following description on msdn:

Indicates if HttpClient operations should be considered completed either as soon as a response is available, or after reading the entire response message including the content.

Using HttpCompletionOption.ResponseHeadersRead the call gets back before the response is read which worked like a charm in my case.

tschuege
  • 761
  • 1
  • 8
  • 20