HttpClient issues - System.Net.WebException: The operation has timed out, no issues with Postman

MetodBMetodB USMember ✭✭

I am scratching my head around this issue for a few days, I decided to ask great Xamarin community for help.
I have a mobile application which is communication with REST API running on IIS over HTTPS.

Android project settings
Minimum Android version: API 15
Target framework: Oreo
HttpClient implementation: Default
SSL/TLS implementation: Native TLS 1.2+

What is the issue?
For example, let's say I have GET api.mydomain.com/user/1 which will return some data.
Calls for most of the users are working just fine, but in some cases when calling user/86, for example, the call fails with a timeout.
I have the timeout set to 30s and after 30s I get:
System.Net.Http.HttpRequestException: An error occurred while sending the request ---> System.Net.WebException: The operation has timed out.
at System.Net.HttpWebRequest+d__241`1[T].MoveNext () [0x000ba] in ...

If I call the same endpoint with Postman, for example, I get a valid response in just a few ms.
I checked on IIS, requests from a mobile application are received and IIS returns 200 with a proper response.

Other requests to the same REST API are working just fine.
This issue can be reproduced in the same environment, always same users are failing.
But with Postman they work just fine. JSON that is returned is well formatted and has no issue that I could see, also it is just a few KB in size.

Did anyone had any similar issues?
Any ideas?

Posts

  • RupertRawnsleyRupertRawnsley GBMember ✭✭✭

    I have a similar problem and I can reproduce it in the attached project. It is a very simple app that downloads two bitmaps:

    https://cdn1.360cities.net/pano/hanyluz/01061142_pano_360.jpg/cube/up/tile/512/2/1/0.jpg
    https://cdn1.360cities.net/pano/hanyluz/01061142_pano_360.jpg/cube/up/tile/512/2/1/1.jpg

    The first one succeeds very quickly and the second one times out after the mandated 10 seconds.

    I can't see any meaningful difference between the two image files and I get the same problem on a Pixel 1 (Android 9) and a Samsung Galaxy S6 (Android 7.0)

    @MetodB Can you try this project on your device to confirm the same behaviour?

    Here is a screen shot of the failure:

  • MetodBMetodB USMember ✭✭

    @RupertRawnsley I gave it a quick try. I can reproduce your issue.

    But your issue is actually different than mine, I get TimeOut error, you are getting TaskCanceled.
    I have one instance of HttpClient for all my API calls.

    I tried to set HttpClient implementation to Android, but the issue is still present.

  • RupertRawnsleyRupertRawnsley GBMember ✭✭✭

    @MetodB Are any of your URLs public and can you share them or replace the image file URLs in my example project with them and test locally? Try CURL or WGET (sometimes in busybox) from ADB on the device that is failing to make sure it's Mono that's at fault.

    On advice from @JonathanPeppers I tried swapping to AndroidClientHandler and the problem went away. I have other issues with that handler, but to be fair it fixes this particular problem.

  • MetodBMetodB USMember ✭✭

    API is not public, sorry I can not share it.

    Thanks for the idea, to call REST API from Android. I tried it using an app called Httper and I got the result.
    So this rules out network or device issues.

  • RupertRawnsleyRupertRawnsley GBMember ✭✭✭

    @MetodB Try swapping HttpClientHandler for AndroidClientHandler (you pass a new instance in the HttpClient constructor).

  • MetodBMetodB USMember ✭✭

    Looks like that issue that I am getting is connected to the Xamarin and/or Xamarin.Android SDK version.
    Colleague build the same code with an older version of Xamarin and that APK worked just fine.

    Problematic version:

    • Visual Studio 15.8.5 (or latest 15.8.9)
    • Xamarin 4.11.0.776
    • Xamarin.Android SDK 9.0.0.19

    Working version:

    • Visual Studio 15.7.6
    • Xamarin 4.10.10.2
    • Xamarin.Android SDK 8.3.3.2

    Code from which the APK was build was the same, only versions of tools are different.

  • MetodBMetodB USMember ✭✭

    Xamarin.Android SDK version 9.0 uses Mono release 5.12.0.
    Looking at Release Notes I found this:

    HttpWebRequest async handling has been rewritten. This resolves many long-standing and hard to reproduce issues involving requests cancellation or timeout. As HttpWebRequest is used as the underlying implementation by other types like HttpClient this should improve the reliability of a broad range of types.

    https://www.mono-project.com/docs/about-mono/releases/5.12.0/#class-libraries

  • DimChrisDimChris USMember ✭✭✭

    Are you sure that is not any network issue? Like firewall or something else? Also i had sum bugs when i used older xamarin's versions. I recommend you to update in latest xamarin's edition

  • MetodBMetodB USMember ✭✭

    Are you sure that is not any network issue?

    No, I am not. I tested on different environments and it worked on some, but on one it didn't, so this would lead me to think that it is a network issue.
    But which is strange is that if I build APK with Visual Studio version 15.7.6 or older (Xamarin 4.10.10.2, Xamarin.Android SDK 8.3.3.2) it works on all environments, there is no issue it works as expected everywhere where I could test.
    But if I build the APK using the latest Visual Studio version which has Xamarin version that uses Xamarin.Android SDK 9.0 or newer I get this error for some API calls, but only on one environment.

    I did not manage to reproduce this issue outside of that environment.

  • DimChrisDimChris USMember ✭✭✭

    I can help you but i need to see some example from your code...

  • WesHollimanWesHolliman USMember
    edited November 2018

    I had the same issue with the latest version as well. I noticed it only happened when I had multiple simultaneous connection attempts to the same endpoint. I was able to resolve my issue by increasing the ConnectionLimit via the ServicePointManager. Hope this helps.

    ServicePointManager.DefaultConnectionLimit = 20;

    Apparently I cannot post a link yet so it's a little butchered below.
    h t t p s://docs.microsoft.com/en-us/dotnet/api/system.net.servicepointmanager.defaultconnectionlimit?view=netframework-4.7.2

    EDIT: After some time I ran into the issue yet again. I went back to the code and realized not all connections were being properly closed.

  • MetodBMetodB USMember ✭✭

    @DimChris what do you need? I can share some parts of the code, but this is a commercial product, so I hope you understand that I will only be able to share small snippets of the code.

    @WesHolliman thanks for sharing.

  • DimChrisDimChris USMember ✭✭✭

    But how someone to help you if he doesn't know what are you using? Example are you use http client in mobile? web client? are you use async routines? Tasks? Get?Post?Your iss is working on local machine? We need some more details... I dont need your whole project, just a sample of what you trying to do... Maybe it's a network problem. Maybe your problem is normal

  • entretoizeentretoize FRMember ✭✭

    I have the same problem; I can reproduce with your images, with the second I have a timeout.
    Did you find a solution ?

  • RupertRawnsleyRupertRawnsley GBMember ✭✭✭

    @entretoize My issue (which probably isn't the same as OPs) was apparently fixed in the Mono trunk, but I haven't confirmed it yet.

  • DimChrisDimChris USMember ✭✭✭

    Your images are transfered as binary or as ascii format?

  • RupertRawnsleyRupertRawnsley GBMember ✭✭✭

    Binary, but it wasn't just image files. About 1 in 20 files at random (always the same files) failed to download.

  • ArneDeVreeseArneDeVreese BEMember ✭✭

    In case someone is still struggling with this. We had the same issue and found, after a long and painstaking investigation, that this was caused by the bug fixed in https://github.com/mono/mono/pull/9228.

    By verifying if the current buffer position after reading the http status (17 in case of "HTTP/1.1 200 OK") is smaller than the remaining size in the buffer (instead of the buffer offset position), an unnecessary read operation was performed on RequestStream.InnerStream which hangs (no data left to read) until a timeout occurs.

    This happens when the response length is (3^[0-n] * 4096) - [0-17]. Which made it hard to simulate.

Sign In or Register to comment.