Facebook SDK 3 EOFException

Я использую новый FaceBook SDK 3.0. При публикации изображений с URL-адреса на «я / фотографии» я периодически получаю EOFException. Я получаю эту ошибку время от времени (~ 1 из 20 раз).

Я также должен добавить, что сразу после получения 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

person Gaurav Vashisth    schedule 05.06.2013    source источник
comment
Была такая ошибка и в Spring Android. Было связано что-то со свойством http.keepalive класса System. Может быть стоит посмотреть.   -  person tolgap    schedule 05.06.2013
comment
В этом случае EOFException означает, что больше нет данных для чтения, что (опять же в этом случае) может означать только то, что файл пуст.   -  person Himanshu Joshi    schedule 22.10.2013
comment
Кто-нибудь нашел решение этой ошибки?   -  person user2106897    schedule 17.02.2014
comment
Я также закодировал повторную попытку, когда error.getErrorMessage().contains(EOF), я думаю, что это ошибка в мороженом-сэндвиче, см. code.google.com/p/android/issues/detail?id=24672   -  person jmhostalet    schedule 10.03.2014
comment
Можете ли вы опубликовать код, который показывает, как вы отправляете сообщения мне / фотографиям? Может просто глюк или глюк при загрузке. Было их много.   -  person napkinsterror    schedule 01.08.2015
comment
Привет, @napkinsterror Я публиковал это так давно, что теперь понятия не имею о своем вопросе.,   -  person Gaurav Vashisth    schedule 05.08.2015
comment
Хорошо, извините. Спасибо, что дал мне знать   -  person napkinsterror    schedule 06.08.2015
comment
если ответ не стоит, проголосуйте, чтобы закрыть его.   -  person Murtaza Khursheed Hussain    schedule 03.11.2015
comment
Это помогло бы показать, как вы обрабатываете логику OutputStream. Возможно, было бы более наглядно увидеть, правильно ли обрабатываются ваши буферы байтов, или есть ли проблема с Dalvik, пытающимся собрать байты, которые вы читаете, в цикле while. (Иногда это может быть проблемой из-за того, как код скомпилирован для повышения производительности. Поэтому, если вы не хотите делиться здесь, вы можете проверить декомпилированный код в своей среде IDE, чтобы увидеть, внес ли компилятор некоторые «полезные корректировки»).   -  person Chris Sullivan    schedule 25.01.2016


Ответы (2)


Эта проблема

Это проблема, связанная с HttpURLConnection. Фактический сокет, используемый для соединения, выбирается из пула. Большинство серверов создают постоянные соединения (заголовок Connection: Keep-Alive), чтобы повторно использовать существующие сокеты, что дешевле, чем создавать каждый раз новый. Проблема заключается в том, что эти сокеты открыты в течение определенного периода времени, в основном 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):

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);) в первый раз.

person Gergely Kőrössy    schedule 18.02.2016

Похоже, у вас могут быть проблемы с подключением к Интернету.

Вы можете написать какой-нибудь retrylogic, чтобы обработать это исключение, отправив его снова, или посмотреть, есть ли у класса, который вы используете для загрузки, способ увеличить время ожидания для транзакции!

person CloudyOne    schedule 16.11.2015