Используя постоянство с Apache HttpClient? - PullRequest
2 голосов
/ 26 июня 2010

Моя цель - подключиться к серверу, а затем поддерживать соединение.Сервер продолжает выдавать мне некоторые данные, когда они есть.Я написал следующее, но это работает только в первый раз.Во второй раз, это дает мне исключение, говоря, что get.getResponseBodyAsStream () является нулевым.Я думал, что HTTPClient Apache поддерживает соединение по умолчанию, так что я понимаю, что мне нужен где-то блокирующий вызов.Может ли кто-нибудь помочь мне здесь?

        GetMethod get = new GetMethod(url);
        String nextLine;
        String responseBody = "";
        BufferedReader input;

        try {
            httpClient.executeMethod(get);
            while(true) {
                try {
                    input = new BufferedReader(new InputStreamReader(get.getResponseBodyAsStream()));

                    while ((nextLine = input.readLine()) != null)
                        responseBody += nextLine;
                    System.out.println(responseBody);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

На самом деле в конце дня я пытаюсь получить постоянное соединение с сервером (позже буду обрабатывать возможные ошибки), чтобы я мог получать обновленияс моего сервера.Любые указатели на это было бы замечательно.

Ответы [ 3 ]

0 голосов
/ 26 июня 2010

Вы не можете сделать это так. Когда вы прочитали «тело» ответа, вот оно. Чтобы получить больше информации, клиент должен отправить новый запрос. Так работает протокол HTTP.

Если вы хотите потоковую передачу нескольких порций данных в одном HTTP-ответе, то вам нужно выполнить разбиение на фрагменты самостоятельно. Существует множество подходов, которые вы можете использовать, в зависимости от характера данных. Например:

  • Если данные представляют собой XML или JSON, отправьте поток документов XML / объектов JSON, а получатель разделит поток на документы / объекты перед отправкой их в анализатор.
  • Придумайте свою собственную легкую «пакетизацию», где вы предшествуете каждому куску стартовым маркером и количеством байтов.

Другой альтернативой является использование нескольких запросов GET, но попытайтесь настроить вещи так, чтобы основное соединение TCP / IP оставалось открытым между запросами; см. Постоянные соединения HTTP .

РЕДАКТИРОВАТЬ

На самом деле мне нужно отправить только один запрос GET и ждать сообщений о состоянии от сервера.

Код состояния HTTP передается в первой строке ответного сообщения HTTP. На HTTP-ответ может быть только один, и (очевидно) может быть только один ответ на HTTP-запрос. Поэтому вы пытаетесь невозможно использовать обычные коды состояния HTTP и сообщения запроса / ответа.

Пожалуйста, просмотрите альтернативы, которые я предложил выше. Направленные на марки альтернативы могут быть изменены, чтобы позволить вам включить некоторый статус в каждую порцию данных. И последний (отправка нескольких запросов) уже решает проблему.

РЕДАКТИРОВАТЬ 2

Чтобы быть более точным, кажется, что поддержание соединения выполнено прозрачно

Это правильно.

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

Если вы не готовы отправить несколько запросов GET (что, очевидно, является самым простым решением !!!), тогда ваш код может выглядеть следующим образом:

 while (true) {
     String header = input.readLine();  // format "status:linecount"
     if (header == null) {
         break;
     }
     String[] parts = header.split(":");
     String status = parts[0];
     StringBuilder sb = new StringBuilder();
     int lineCount = Integer.parseInt(parts[1]);
     for (int i = 0; i < lineCount; i++) {
         String line = input.readLine();
         if (line == null) {
             throw new Exception("Ooops!");
         }
         sb.append(line).append('\n');
     }
     System.out.println("Got status = " + status + " body = " + body);
  }

Но если вы отправляете только коды состояния или если остальная часть каждого блока данных может быть вставлена ​​в ту же строку, вы можете еще больше упростить это.

Если вы пытаетесь реализовать это так, чтобы вашему основному потоку не приходилось ждать (блокировать) чтения из входного потока, то либо используйте NIO, либо используйте отдельный поток для чтения из входного потока.

0 голосов
/ 26 июня 2010

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

0 голосов
/ 26 июня 2010

Я не смотрел подробно и не тестировал код, но я думаю, что многократное открытие читателя по ответу, вероятно, плохая идея. Я бы взял и переместил линию input = вне петли, для начала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...