2010-06-15 35 views
40
Cập nhật: Tìm thấy câu trả lời bản thân mình, xem dưới đây :-)

Hi,Yêu cầu đăng bài HTTP bằng cách sử dụng HttpClient mất 2 giây, tại sao?

I'am hiện mã hóa một ứng dụng android mà nộp thứ trong nền sử dụng HTTP Bưu AsyncTask. Tôi sử dụng gói org.apache.http.client cho việc này. Tôi dựa trên mã của tôi trên this example.

Về cơ bản, mã của tôi trông như thế này:

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()); 
    } 
} 

Vấn đề là các httpclient.execute (..) dòng mất khoảng 1,5-3 giây, và tôi không hiểu tại sao. Chỉ cần yêu cầu một trang với HTTP Get mất khoảng 80 ms hoặc lâu hơn, do đó, vấn đề dường như không phải là độ trễ của mạng.

Vấn đề dường như không ở phía máy chủ, tôi cũng đã thử gửi dữ liệu tới http://www.disney.com/ với kết quả chậm tương tự. Và Firebug hiển thị thời gian phản hồi 1 ms khi POST dữ liệu lên máy chủ của tôi cục bộ.

Điều này xảy ra trên Trình mô phỏng và với Nexus One của tôi (cả với Android 2.2).

Nếu bạn muốn xem mã hoàn chỉnh, tôi đã đặt nó trên GitHub.

Nó chỉ là một chương trình giả để thực hiện HTTP Post trong nền bằng cách sử dụng AsyncTask khi ấn nút. Đây là ứng dụng Android đầu tiên của tôi và mã java đầu tiên của tôi trong một thời gian dài. Và tình cờ, cũng là câu hỏi đầu tiên của tôi về Stackoverflow ;-)

Bất kỳ ý tưởng nào tại sao httpclient.execute (httppost) mất quá nhiều thời gian?

+0

Tôi đang gặp phải vấn đề tương tự này, ngoại trừ tệ hơn nhiều. Nó thậm chí có thể mất tới 20 giây để hoàn thành một 'HttpPost'.Tôi đã cố gắng sửa chữa của bạn nhưng nó dường như không giúp đỡ bạn. – theblang

Trả lời

55

Được rồi, tôi đã tự giải quyết vấn đề này với một số điều tra khác. Tất cả tôi phải làm là thêm một tham số mà bộ phiên bản HTTP đến 1.1, như sau:

HttpParams params = new BasicHttpParams(); 
params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); 
HttpClient httpclient = new DefaultHttpClient(params); 

Tôi thấy điều này nhờ vào sự rất đẹp HttpHelper Class từ và mọt sách và một số thử nghiệm và báo lỗi.

Nếu tôi nhớ chính xác, HTTP 1.0 sẽ mở một kết nối TCP mới cho mọi yêu cầu. Điều đó giải thích sự chậm trễ lớn?

Yêu cầu HTTP POST hiện mất từ ​​50 đến 150 ms qua WLAN và khoảng từ 300 đến 500 ms qua 3G.

+2

đơn giản hơn một chút (nhưng tương đương): HttpProtocolParams.setVersion (params, HttpVersion.HTTP_1_1); –

+12

Thay vì giải pháp phiên bản - tại sao lại hoạt động? - Tôi đề nghị giải pháp đơn giản hơn, 'httppost.getParams(). SetBooleanParameter (CoreProtocolPNames.USE_EXPECT_CONTINUE, false);' –

+1

dude - tôi đang tìm kiếm ngẫu nhiên về chủ đề này giữa các bài kiểm tra cho ứng dụng của tôi vì nó quá chậm - thay đổi này làm cho nó hét lên. CẢM ƠN BẠN. – bsautner

6

tôi không ở trên Android, nhưng tôi phải đối mặt chính xác cùng một loại vấn đề trên nền tảng cửa sổ với httpclient 4.0.1, sau khi khá một chút gãi đầu, tôi tìm thấy giải pháp.

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); 

tôi không biết tại sao cài đặt thông số với phiên bản HTTP1.1 giải quyết được sự cố. nhưng nó có. thậm chí còn hơn nữa, các triệu chứng không hiển thị nếu thực hiện yêu cầu Nhận HTTP.

dù sao đi chăng nữa, tôi hy vọng điều này sẽ giúp ích cho bạn!

h

Các vấn đề liên quan