Ответ HttpURLConnection POST теряется, когда серверу требуется больше времени для ответа

У меня возникли проблемы с получением ответа на POST-запрос к серверу, когда серверу требуется немного больше времени для ответа (когда он передается большим JSONObject).

Когда мы вызываем метод GET с более длительным временем отклика, проблем не возникает. Когда мы вызываем POST и передаем относительно небольшой JSONObject, метод регистрирует ответ. Метод вызывается из AsyncTask через new Task().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR).

При срабатывании Postman ответ возвращается через 155 секунд, но приходит. С другой стороны, при запуске из приложения код ничего не делает и в конечном итоге вызывает SocketTimeoutException. (По какой-то причине у нас есть тайм-аут (тайм-аут подключения и чтения), установленный на 10 минут). Ниже приведен фрагмент кода для метода службы. . Буду признателен за любые подсказки.

public static JSONObject requestWebService(String serviceUrl, JSONObject jsonObject) throws Exception {
    private static final int CONNECTION_TIMEOUT = 1000 * 600; 
    private static final int DATARETREIVAL_TIMEOUT = 1000 * 600
    HttpURLConnection urlConnection = null;
    try {
        URL urlToRequest;
        String message;

        urlToRequest = new URL(serviceUrl);

        urlConnection = (HttpURLConnection) urlToRequest.openConnection();
        urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
        urlConnection.setReadTimeout(DATARETREIVAL_TIMEOUT);

        if (jsonObject != null) {
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);
            urlConnection.setRequestMethod("POST");
            urlConnection.setRequestProperty("Content-Type", "application/json");

            message = jsonObject.toString();

            OutputStream os = new BufferedOutputStream(urlConnection.getOutputStream());
            os.write(message.getBytes());
            os.flush();
            os.close();
        } else {
            urlConnection.setRequestMethod("GET");
        }

        int statusCode = urlConnection.getResponseCode();
        if (statusCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
            throw new Exception("Acces unauthorized " + statusCode + ".");
        } else if (statusCode != HttpURLConnection.HTTP_OK) {
            throw new Exception("Server unavailable " + statusCode + ".");
        }

    return new JSONObject(ReplicationClient.convertInputStreamToString(urlConnection.getInputStream()));

    } catch (MalformedURLException e) {
        fileLogger.error(logHeader + e.getMessage(), e);
        throw new Exception("Error " + e.getMessage(), e);
    } catch (SocketTimeoutException e) {
        fileLogger.error(logHeader + e.getMessage(), e);
        throw new Exception("Error  " + e.getMessage(), e);
    } catch (IOException e) {
        fileLogger.error(logHeader + e.getMessage(), e);
        throw new Exception("Error  " + e.getMessage(), e);
    } catch (JSONException e) {
        fileLogger.error(logHeader + e.getMessage(), e);
        throw new Exception("Error  " + e.getMessage(), e);
    } catch (Exception e) {
        fileLogger.error(logHeader + e.getMessage(), e);
        throw new Exception("Error  " + e.getMessage(), e);
    } finally {
        if (urlConnection != null) {
            urlConnection.disconnect();
        }
    }
}

person barmacki    schedule 28.11.2016    source источник
comment
каковы значения для CONNECTION_TIMEOUT и DATARETREIVAL_TIMEOUT ? известно ли вам, что эти методы принимают значение в миллисекундах? я думаю, вы установили значения, как если бы они были секундами?   -  person Yazan    schedule 28.11.2016
comment
Извините, вот они: private static final int CONNECTION_TIMEOUT = 1000 * 600; private static final int DATARETREIVAL_TIMEOUT = 1000 * 600;   -  person barmacki    schedule 28.11.2016
comment
Только что заметил, что объект OutputStream не был закрыт, может ли это быть проблемой?   -  person rhari    schedule 28.11.2016
comment
значения выглядят хорошо для меня, вы знаете, через сколько времени выдается исключение?   -  person Yazan    schedule 28.11.2016
comment
он просто висит там, а затем просто выдает исключение тайм-аута (через 10 минут, интервал времени, который мы установили). @rhari, я пытался закрыть объект OutputStream, но это не имело никакого значения.   -  person barmacki    schedule 28.11.2016
comment
возможно, используемое вами устройство потребляет соединение в некоторых других приложениях, поэтому ответ задерживается   -  person Umar Ata    schedule 29.11.2016
comment
после того, как моя теория провалилась, теперь мы начинаем искать странные ответы :)... как насчет добавления заголовка длины содержимого? вот так urlConnection.setRequestProperty("Content-Length", "" + jsonObject.toString().getBytes("UTF8").length); поставить сразу после Content-Type строки   -  person Yazan    schedule 29.11.2016


Ответы (1)


после секундного размышления у меня есть теория, которую я объясню в деталях

но сначала попробуйте этот код для записи данных:

удалите это из своего кода:

OutputStream os = new BufferedOutputStream(urlConnection.getOutputStream());
os.write(message.getBytes());
os.flush();
os.close();

используйте это:

OutputStream os = urlConnection.getOutputStream();
os.write( message.getBytes());    
os.close();

если это сработает, я отредактирую этот ответ и объясню подробнее.

Этот ответ не помог согласно комментарию ОП. Я сохраняю это на случай, если найду что-то еще, в противном случае я удалю это позже.

person Yazan    schedule 28.11.2016
comment
к сожалению, нет, похоже, это не имеет никакого значения. - person barmacki; 28.11.2016