TCP-соединение не используется повторно для HTTP-запросов с HttpURLConnection

Я создал приложение, которое отправляет запросы GET на URL-адрес, а затем загружает полное содержимое этой страницы.

Клиент отправляет GET, например. stackoverflow.com и перенаправляет ответ анализатору, который должен найти все исходники со страницы, которые необходимо загрузить с последующими запросами GET.

Метод ниже используется для отправки этих запросов GET. Он вызывается много раз подряд, и анализатор возвращает URL-адреса. Большинство этих URL-адресов расположены на одном и том же хосте и должны иметь возможность совместно использовать TCP-соединение.

public static void sendGetRequestToSubObject(String RecUrl)
    {
        URL url = new URL(recUrl.toString());
        URLConnection connection = url.openConnection ();
        InputStreamReader isr = new InputStreamReader(connection.getInputStream());
    }

Каждый раз, когда вызывается этот метод, создается новое TCP-соединение (с трехсторонним рукопожатием TCP), а затем по этому соединению отправляется GET. Но я хочу повторно использовать соединения TCP для повышения производительности.

Я предполагаю, что, поскольку я создаю новый объект URL каждый раз, когда вызывается метод, именно так он и будет работать...

Может быть, кто-то может помочь мне сделать это лучше?

Спасибо!


person plithner    schedule 28.03.2011    source источник


Ответы (2)


HttpURLConnection будет повторно использовать подключения если это возможно!

Чтобы это работало, необходимо выполнить несколько предварительных условий, в основном на стороне сервера. Эти предварительные условия описаны в статье, ссылка на которую приведена выше.

person Joachim Sauer    schedule 28.03.2011
comment
Спасибо! Я ознакомился с этим документом и считаю, что предварительные условия выполнены. Я знаю, что сервер выполняет их, потому что я пытался получить доступ к URL-адресам с помощью нескольких разных браузеров (IE, Chrome, FIrefox), и во всех случаях TCP-соединение повторно используется для нескольких HTTP GET. - person plithner; 28.03.2011
comment
Я все еще думаю, что делаю что-то не так в коде... Например, тот факт, что для каждого URL-адреса я создаю новый объект URL-адреса. Это кажется неправильным, но я не мог поступить иначе. - person plithner; 28.03.2011
comment
@user: поскольку URL объекты не могут быть изменены, вам нужно каждый раз создавать новый, так что это, конечно, не проблема. - person Joachim Sauer; 28.03.2011
comment
Извините за такой комментарий к моему собственному сообщению ... но я понимаю, что вы (Иоахим) имели в виду следующее: но базовое сетевое соединение с HTTP-сервером может быть прозрачно доступно другим экземплярам. Я предполагаю, что тогда создание нового экземпляра для каждого GET будет в порядке. Любые другие идеи, что я могу делать неправильно? Я попытался добавить connection.setRequestProperty(Connection,keep-alive); Но это не помогает. - person plithner; 29.03.2011
comment
Еще немного информации: я обнаружил, что при доступе к определенному URL-адресу (www.itunes.com) я вижу, что некоторые GET отправляются по тому же TCP-соединению. Отличные новости, но лишь немногие из GET отправляются таким образом. При использовании реального браузера для доступа к тому же URL-адресу по тому же соединению отправляется еще несколько запросов. Конечным результатом является то, что моему клиенту требуется в несколько раз больше времени для загрузки страницы. - person plithner; 29.03.2011
comment
Есть ли решение для этого сценария? - person SkyEagle888; 21.02.2014

Нашел проблему! Я неправильно читал входной поток. Это приводило к зависанию объектов входного потока, и их нельзя было использовать повторно.

Я только определил это, вот так:

InputStreamReader isr = new InputStreamReader(connection.getInputStream());

но я никогда не читал оттуда :-)

Я также изменил метод чтения. Вместо буферизованного ридера я украл вот это:

InputStream in = null; 
String queryResult = "";
try {
     URL url = new URL(archiveQuery);
     HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
     HttpURLConnection httpConn = (HttpURLConnection) urlConn;
     httpConn.setAllowUserInteraction(false);
     httpConn.connect();
     in = httpConn.getInputStream();
     BufferedInputStream bis = new BufferedInputStream(in);
     ByteArrayBuffer baf = new ByteArrayBuffer(50);
     int read = 0;
     int bufSize = 512;
     byte[] buffer = new byte[bufSize];
     while(true){
         read = bis.read(buffer);
         if(read==-1){
           break;
         }
         baf.append(buffer, 0, read);
     }
     queryResult = new String(baf.toByteArray());
     } catch (MalformedURLException e) {
          // DEBUG
          Log.e("DEBUG: ", e.toString());
     } catch (IOException e) {
          // DEBUG
          Log.e("DEBUG: ", e.toString());
     } 
}

Отсюда: Чтение HttpURLConnection InputStream — ручной буфер или BufferedInputStream?

person plithner    schedule 29.03.2011