51

我正在使用新的 Facebook SDK 3.0。在将图像从 URL 发布到“我/照片”时,我间歇性地得到一个EOFException. 我偶尔会收到此错误(约 20 次中的 1 次)。

我还必须补充一点,EOFException如果我再次重试发布,它会成功发布。

EOFException因此,暂时我已经编写了代码,如果我得到并且解决方案似乎令人满意,则自动重试一次。

但我需要知道是什么导致了它,它是 Android SDK 中的一个错误。我用谷歌搜索了很多,但什么也得不到。

我正在发布日志(出于安全原因删除我的访问令牌和图像 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
4

2 回答 2

1

问题

这是一个HttpURLConnection相关的问题。用于连接的实际套接字是从池中选择的。大多数服务器创建持久连接(Connection: Keep-Alive标头)以重用现有套接字,这比每次创建一个新套接字要便宜。问题出在这些socket打开了一段时间,大多是60秒左右,然后就关闭了,不能再使用了。然而,Android 操作系统尝试使用相同的套接字,因为它认为套接字仍然是好的,因为它被分配给了同一个主机,所以它开始发送等待 ACK 的包和其他响应包,因为套接字是不再开放,尽管它​​一直在期待一些答案,因此EOFException.

解决方案

第 1 步 - 将池大小限制为相对较小的数字

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

第 2 步 - 实施重试机制

无论您在何处使用 Facebook 代码并获得一个EOFException,都将其包装在一个 try-catch 中,该捕获异常并重试连接到最大池大小的 URL。这是一个可以使用的方法存根(我不知道 Facebook SDK,因此是TODO's):

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
    }
} 

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

于 2016-02-18T21:27:55.707 回答
0

听起来您可能遇到了一些互联网连接问题。

你可以写一些重试逻辑来处理这个异常,让它再次提交,或者看看你用来上传的类是否有办法增加事务的超时!

于 2015-11-16T21:47:34.600 回答