Facebook SDK 3 EOFException

我正在使用新的FaceBook SDK 3.0。 当从URL发送图像到“我/照片”,我间歇性地得到一个EOFException 。 我偶尔会遇到这个错误(约20次)。

我还必须添加,如果我再次重试发布EOFException后,它成功发布。

所以,暂时我编码自动重试一次,如果我得到EOFException并且解决scheme似乎令人满意。

但是我需要知道是什么造成的,这是Android SDK中的一个错误。 我search了很多,但没有得到任何东西。

我发布日志(出于安全原因删除我的访问令牌和图像的URL)

 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 <Error>: java.io.EOFException 

问题

这是一个HttpURLConnection相关的问题。 从连接池中select用于连接的实际套接字。 大多数服务器创build持久连接( Connection: Keep-Alive头),以便重复使用现有的套接字,比每创build一个套接字便宜。 问题来自于这些sockets打开了一段时间,大部分是60秒左右,然后closures了,不能重复使用。 然而,Android操作系统尝试使用相同的套接字,因为它被分配到相同的主机,因此套接字仍然是好的,所以它开始发送等待ACK和其他响应包的包,不再开放,虽然它期待一些答案,因此EOFException

解决scheme

第1步 – 限制池大小相对较小的数字

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

第2步 – 实施重试机制

无论您在哪里使用Facebook代码并获取EOFException ,都会将其封装在try-catch中,以捕获exception并重试连接到最大池大小的URL。 这里有一个方法存根,可以使用( 我不知道Facebook的SDK,因此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 } } 

当然,你必须第一次用0 retryNumber( connect(0); )来调用这个方法。

这听起来像你可能有一些互联网连接问题。

你可以写一些retrylogic来通过再次提交来处理这个exception,或者看看你用来上传的类是否有办法增加事务的超时时间!