Facebook SDK 3 EOFException

The problem

This is a HttpURLConnection related issue. The actual socket used for the connection is selected from a pool. Most servers create persistent connections (Connection: Keep-Alive header) in order to reuse existing sockets which is cheaper than creating a new one every single time. The problem comes from the fact that these sockets are open for a certain period of time, mostly 60 seconds or so, then they are closed and cannot be reused. The Android OS, however, tries to use the same socket as it thinks that the socket is still good since it was assigned to the same host, so it starts sending packages waiting for ACK and other response packages, which never come since the socket is not open anymore, though it’s been expecting some answer, hence the EOFException.

The solution

Step 1 – Limit the pool size to a relatively small number

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

Step 2 – Implement a retry mechanism

Wherever you use the Facebook code and get an EOFException, wrap it in a try-catch that catches the exception and retries connecting to the URL up to the max pool size. Here’s a method stub, that could be used (I don’t know the Facebook SDK, hence the 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
    }
} 

Of course, you have to call this method with 0 retryNumber (connect(0);) the first time.

Leave a Comment

tech