HTTP-запросы с использованием HttpClient занимают 2 секунды, почему?
Обновление:
Нашел ответ сам, см. Ниже: -)
Привет,
В настоящее время я кодирую приложение Android, которое передает материал в фоновом режиме с помощью HTTP Post и AsyncTask. Я использую org.apache.http.client Пакет для этого. Я основывал свой код на в этом примере.
В принципе, мой код выглядит следующим образом:
public void postData() {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://192.168.1.137:8880/form");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("id", "12345"));
nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
Log.e(TAG,e.toString());
} catch (IOException e) {
Log.e(TAG,e.toString());
}
}
Проблема в том, что строка httpclient.execute(..) занимает около 1,5-3 секунд, и я не понимаю, почему. Просто запрос страницы с HTTP Get занимает около 80 мс или около того, поэтому проблема не является самой локальной задержкой.
Проблема, похоже, не на стороне сервера, я также попробовал данные POSTing для http://www.disney.com/ с аналогичными медленными результатами, И Firebug показывает время отклика 1 мс при отправке данных на мой сервер локально.
Это происходит в эмуляторе и с моим Nexus One (оба с Android 2.2).
Если вы хотите посмотреть полный код, я положил его на GitHub.
Это просто фиктивная программа, чтобы сделать HTTP-сообщение в фоновом режиме, используя AsyncTask нажатием кнопки. Это мое первое приложение для Android и мой первый Java-код в течение длительного времени. И, кстати, также мой первый вопрос о Stackoverflow; -)
Любые идеи, почему httpclient.execute(httppost) занимает так много времени?
Ответы
Ответ 1
Хорошо, я решил это сам с еще одним исследованием. Все, что мне нужно было сделать, это добавить параметр, который устанавливает версию HTTP версии 1.1 следующим образом:
HttpParams params = new BasicHttpParams();
params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpClient httpclient = new DefaultHttpClient(params);
Я нашел это благодаря очень приятному HttpHelper Class от и-bookworm и некоторым пробным ошибкам.
Если я правильно помню, HTTP 1.0 открывает новое TCP-соединение для каждого запроса. Это объясняет большую задержку?
Запрос HTTP POST теперь занимает от 50 до 150 мс по WLAN и что-то между 300 и 500 мс по 3G.
Ответ 2
Я не на Android, но я столкнулся с такой же проблемой на платформе Windows с помощью httpclient 4.0.1, после того, как немного поцарапал голову, я нашел решение.
HttpParams params = new BasicHttpParams();
//this how tiny it might seems, is actually absoluty needed. otherwise http client lags for 2sec.
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpClient httpClient = new DefaultHttpClient(params);
HttpResponse httpResponse;
HttpPost httpPost = new HttpPost("http://"+server+":"+port+"/");
StringEntity entity = new StringEntity(content, "utf-8");
entity.setContentType("text/plain; charset=utf-8");
httpPost.setEntity(entity);
httpResponse=httpClient.execute(httpPost);
String response = IOUtils.toString(httpResponse.getEntity().getContent(),encoding);
httpResponse.getEntity().consumeContent();
httpClient.getConnectionManager().shutdown();
return(response);
Я не знаю, почему настройка параметров с версией HTTP1.1 решает проблему. но это так.
также даже более странный, симптом не показывался при выполнении запроса HTTP Get.
во всяком случае, я надеюсь, что это поможет кому-то там!
ч