6
votes

Comment réparer une exception "java.io.IOException: fin de flux inattendue lors de la connexion" dans HTTPClient sur .NetStandard

Je me gratte la tête avec celui-ci depuis un moment. Je construis une application Android dans Xamarin et j'ai une demande de connexion POST qui fonctionne principalement, mais qui recevra parfois cette erreur. J'informe l'utilisateur et lui dis de réessayer, mais j'obtiens toujours l'erreur beaucoup trop souvent et je veux le corriger afin que l'application offre une expérience plus fluide.

Voici la trace de la pile que j'ai connectée sur App Center: p>

LoginProvider+d__1.MoveNext () C:\source\repos{MyApp}{MyApp}{MyApp}\Services\LoginProvider.cs:35
java.io.IOException: unexpected end of stream on Connection{testclarity.i-menzies.com:443, proxy=DIRECT@ hostAddress=62.244.173.166 cipherSuite=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 protocol=http/1.1} (recycle count=0)
com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:210)
com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:905)
com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:789)
com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:443)
com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:388)
com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:501)
com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:25)
Caused by: java.io.EOFException: \n not found: size=0 content=...
com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:200)
com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191)

J'utilise .NETStandard 2.0, avec Xamarin Forms 3.2.0.871581.

J'ai parcouru la majeure partie de Google et identifié qu'il s'agit d'un problème avec divers Android bibliothèques, en particulier OkHttp (le même que celui mentionné dans ma trace de pile). J'ai essayé d'enquêter sur la source .NETStandard sur Github pour identifier la cause possible, mais je trouve le projet très difficile à naviguer, d'autant plus que ce problème semble être spécifique à Android. Tout conseil pour trouver la bonne source serait idéal.

Ce que j'ai essayé sur la base de suggestions d'Internet:

  • Définition de mon en-tête de connexion fermé.
  • Définition de mon codage de transfert en morceaux.
  • Remplacement de l'implémentation Android HttpClient de Android par défaut dans les propriétés du projet Android.

Celles-ci semblent faire partie des suggestions en ligne les plus populaires, dont certaines fonctionnent pour les gens, d'autres non.

Une autre suggestion courante consiste à définir la configuration de la bibliothèque OkHttp sur OkHTTP.setRetryOnConnectionFailure (true), ce qui résout apparemment le problème pour de nombreuses personnes, comme suggéré ici: https://github.com/square/okhttp/issues/1517#issuecomment-144069139 .

Aussi , un bogue similaire semble avoir été déposé dans Xamarin.Android ici: https: // bugzilla. xamarin.com/show_bug.cgi?id=41100 . Mais cela a été marqué comme corrigé. Je ne sais pas si cela alimentera mon projet Xamarin Forms.

Quelqu'un sait-il comment je peux résoudre ce problème ou comment je peux enquêter plus loin que ce que j'ai déjà essayé?


6 commentaires

Essayez d'éviter la pile OkHttp en utilisant Managed HttpClientHandler avec l'implémentation BoringSLL SSL.TLS, du moins s'il s'agit d'un problème client (c'est-à-dire le timing de maintien en vie) et non d'un problème de serveur (le serveur ferme la connexion de socket keep alive ) (De plus, quel est le délai de conservation sur votre serveur? Et pouvez-vous l'augmenter?)


@SushiHangover - Je vais expérimenter avec Managed HttpClientHandler et BoringSLL, comme vous l'avez recommandé. Je devrai vérifier auprès de mon équipe la durée de conservation sur le serveur car je ne sais pas comment cela est configuré. Merci pour les suggestions, je ferai un rapport car je souhaite aider tous les développeurs Xamarin qui pourraient rencontrer ce même problème!


Des mises à jour sur ce problème?


Salut @NathanCrama. Suite à la suggestion utile de SushiHangover, j'ai plutôt basculé mon projet Android vers l'implémentation du client Android, comme détaillé dans cet article ici: github.com/xamarin/xamarin-android/issues/… . Je n'ai pas vu le problème depuis que j'ai fait cela.


D'accord merci. J'espérais quelque chose d'un peu mieux car Microsoft ne semble pas encourager cette voie, selon cette page: docs.microsoft.com/en-us/xamarin/android/app-fundamentals/... , mais merci pour votre réponse quand même.


Au contraire, sur la base du lien que vous avez fourni, il semble que Microsoft encourage activement l'utilisation de la configuration du client Android comme je le fais: avril 2018 "Afin de vous assurer que vos applications continuent à fonctionner avec ces serveurs et services, vous devez mettre à jour votre Projets Xamarin avec les paramètres Android HttpClient et Native TLS 1.2 indiqués ci-dessous, puis recréez et redéployez vos applications auprès de vos utilisateurs. "


3 Réponses :


4
votes

Après avoir suivi les informations de ce lien: https://docs.microsoft.com/en-us/xamarin/android/app-fundamentals/http-stack?tabs=macos

Et en remplaçant mon HTTPHandler par le gestionnaire natif d'Android:

La configuration Xamarin.Android HttpClient est dans les options du projet> Options Android, puis cliquez sur le bouton Options avancées.

Voici les paramètres recommandés pour la prise en charge de TLS 1.2:

Options Android de Visual Studio

 entrez la description de l'image ici

Le petit plus que j'ai manqué est:

Les projets doivent référencer l'assembly System.Net.Http.

Assurez-vous que votre projet fait référence à System.Net.Http sinon il utilisera toujours OKHttp


0 commentaires

0
votes

Vous pouvez simplement accéder au fichier Projet Android> Propriétés> AssemblyInfo.cs. Ouvrez le fichier AssemblyInfo et ajoutez la ligne suivante à la fin:

[assembly: Application (UsesCleartextTraffic = true)]

Cela m'a aidé à résoudre mon problème. J'espère que cela vous aidera aussi


0 commentaires

0
votes

J'avais le même problème et je recherchais ce correctif. Ma référence de projet à System.Net.Http. J'étais en train de remplacer mon HTTPHandler par le gestionnaire Android natif lorsque j'ai obtenu cette exception, mais j'ai obtenu une exception système un peu similaire lors de l'utilisation d'un HTTPHandler différent. J'ai essayé de nombreuses suggestions et j'ai finalement résolu le problème en utilisant https dans mon URL de base. Voici ma référence: https://github.com/square/okhttp/issues/ 1517 # issuecomment-560486265

IMO, le correctif peut être différent dans chaque cas, vous pouvez donc essayer d'autres suggestions.


0 commentaires