Facebook SDK 3 EOFException

J’utilise le nouveau SDK FaceBook 3.0. En postant des images de l’URL sur “moi / photos”, je reçois par intermittence une EOFException . Je reçois cette erreur de temps en temps (~ 1 à 20 fois).

Je dois également append que juste après avoir obtenu l’ EOFException si je réessaye à nouveau la publication, il publie avec succès.

Donc, pour le moment, j’ai codé pour réessayer automatiquement une fois de plus si j’obtiens EOFException et que la solution semble satisfaisante.

Mais j’ai besoin de savoir ce qui le cause, est-ce un bug dans le SDK Android. Je l’ai beaucoup consulté mais je n’ai rien pu obtenir.

Je publie les journaux (suppression de mon jeton d’access et de mon URL d’image pour des raisons de sécurité)

 06-05 15:09:42.585: D/FacebookSDK.Request(16611): Request: 06-05 15:09:42.585: D/FacebookSDK.Request(16611): Id: 9 06-05 15:09:42.585: D/FacebookSDK.Request(16611): URL:https://graph.facebook.com/me/photos?caption=abc&format=json&sdk=android&migration_bundle=fbsdk%3A20121026&access_token=ADBCEFG&url=http%3A%2F%2Ftest.test.test%2Ftest%2Ftest%2F201695%2Ftest%2F18629 06-05 15:09:42.585: D/FacebookSDK.Request(16611): Method: POST 06-05 15:09:42.585: D/FacebookSDK.Request(16611): User-Agent: FBAndroidSDK.3.0.0 06-05 15:09:42.585: D/FacebookSDK.Request(16611): Content-Type: multipart/form-data; boundary=3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f 06-05 15:09:42.585: D/FacebookSDK.Request(16611): Parameters: 06-05 15:09:42.585: D/FacebookSDK.Request(16611): caption: abc 06-05 15:09:42.585: D/FacebookSDK.Request(16611): format: json 06-05 15:09:42.585: D/FacebookSDK.Request(16611): sdk: android 06-05 15:09:42.585: D/FacebookSDK.Request(16611): migration_bundle: fbsdk:20121026 06-05 15:09:42.585: D/FacebookSDK.Request(16611): access_token: ABCDEF 06-05 15:09:42.585: D/FacebookSDK.Request(16611): url: http://test.test.test/test/test/201695/test/18629 06-05 15:09:42.585: D/FacebookSDK.Request(16611): Attachments: 06-05 15:09:42.600: D/FacebookSDK.Response(16611): Response : java.io.EOFException 

Le problème

Ceci est un HttpURLConnection lié à HttpURLConnection . Le socket utilisé pour la connexion est sélectionné dans un pool. La plupart des serveurs créent des connexions persistantes (en Connection: Keep-Alive tête Connection: Keep-Alive ) afin de réutiliser les sockets existants, ce qui est moins coûteux que d’en créer un à chaque fois. Le problème vient du fait que ces sockets sont ouverts pendant un certain temps, la plupart du temps environ 60 secondes, puis ils sont fermés et ne peuvent pas être réutilisés. Le système d’exploitation Android, cependant, essaie d’utiliser le même socket car il pense que le socket est toujours correct puisqu’il a été assigné au même hôte, il commence donc à envoyer des paquets en attente d’ACK et d’autres paquets de réponse ne plus s’ouvrir, même si on s’attendait à une réponse, d’où l’ EOFException .

La solution

Étape 1 – Limitez la taille du pool à un nombre relativement petit

 private static final int MAX_CONNECTIONS = 5; // ... static { System.setProperty("http.maxConnections", Ssortingng.valueOf(MAX_CONNECTIONS)); } 

Étape 2 – Implémentez un mécanisme de nouvelle tentative

Où que vous EOFException le code Facebook et que vous obteniez une EOFException , enveloppez-le dans un try-catch qui intercepte l’exception et réessaie de se connecter à l’URL jusqu’à la taille maximale du pool. Voici un stub de méthode, qui pourrait être utilisé ( je ne connais pas le SDK Facebook, donc le TODO ):

 private void connect(int retryNumber) { try { // TODO your facebook code goes here } catch (EOFException e) { if (retryNumber > MAX_CONNECTIONS) { // TODO handle exception, it's over the limit, so it is a different problem } else { // TODO disconnect first, if possible connect(retryNumber + 1); } } catch (Exception e) { // TODO other exception handling } finally { // TODO disconnect, if possible } } 

Bien sûr, vous devez appeler cette méthode avec 0 retryNumber ( connect(0); ) la première fois.

Il semble que vous ayez des problèmes de connectivité Internet.

Vous pouvez écrire à certains retrylogic pour gérer cette exception en la soumettant à nouveau, ou voir si la classe que vous utilisez pour télécharger a un moyen d’augmenter le délai d’expiration de la transaction!