Android. Как открыть постоянное HTTP-соединение, которое получает фрагментированные ответы?

Я пытаюсь установить постоянное HTTP-соединение с конечной точкой API, которая публикует разрозненные ответы JSON по мере возникновения новых событий. Я хотел бы предоставить обратный вызов, который вызывается каждый раз, когда сервер отправляет новый фрагмент данных, и держать соединение открытым на неопределенный срок. Насколько я могу судить, ни HttpClient, ни HttpUrlConnection не предоставляют эту функциональность.

Есть ли способ сделать это без использования сокета TCP?


person allenc    schedule 20.08.2014    source источник
comment
любые решения для этого? Я пытаюсь сделать то же самое.   -  person akbas    schedule 24.11.2014
comment
@akbas Я разместил решение с использованием HttpClient: stackoverflow.com/a/27430319/3875216   -  person allenc    schedule 11.12.2014


Ответы (2)


Одним из решений было бы использование разделителя, такого как \n\n, для разделения каждого события json. Вы можете удалить пустые строки из исходного json перед отправкой. Вызов setChunkedStreamingMode(0) позволяет вам читать контент по мере его поступления (а не после буферизации всего запроса). Затем вы можете просто просмотреть каждую строку, сохраняя их, пока не будет достигнута пустая строка, а затем проанализировать сохраненные строки как JSON.

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setChunkedStreamingMode(0);
conn.connect();

InputStream is = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
StringBuffer sBuffer = new StringBuffer();
String line;
while ((line = reader.readLine()) != null) {
    if (line.length() == 0) {
        processJsonEvent(sBuffer.toString());
        sBuffer.delete(0, sBuffer.length());
    } else {
        sBuffer.append(line);
        sBuffer.append("\n");
    }
}
person snydergd    schedule 28.06.2016

Насколько я могу судить, Android HttpURLConnection не поддерживает получение фрагментов данных через постоянное HTTP-соединение; вместо этого он ожидает полного завершения ответа.

Однако использование HttpClient работает:

HttpClient httpClient = new DefaultHttpClient();

try {
    HttpUriRequest request = new HttpGet(new URI("https://www.yourStreamingUrlHere.com"));
} catch (URISyntaxException e) {
    e.printStackTrace();
}

try {
    HttpResponse response = httpClient.execute(request);
    InputStream responseStream = response.getEntity().getContent();
    BufferedReader rd = new BufferedReader(new InputStreamReader(responseStream));

    String line;
    do {
        line = rd.readLine();
        // handle new line of data here
    } while (!line.isEmpty());


    // reaching here means the server closed the connection
} catch (Exception e) {
    // connection attempt failed or connection timed out
}
person allenc    schedule 11.12.2014
comment
к сожалению, HttpClient устарел в пользу HttpURLConnection (и он был удален в Android 6). - person bj0; 27.10.2015
comment
я думаю, что вы ошибаетесь насчет HttpURLConnetction, он может получать данные фрагмента с помощью обработчика SAX. - person Rashid; 28.06.2016