2009-06-18 34 views
18

Là một newbie tương đối trong thế giới Java, tôi đang tìm kiếm nhiều điều bực bội để thực hiện điều đó là tương đối nhỏ nhặt trong nhiều khung công tác khác. Ví dụ chính là một giải pháp đơn giản cho các yêu cầu http không đồng bộ. Nhìn như một dường như không tồn tại, cách tiếp cận tốt nhất là gì? Tạo chủ đề của riêng tôi bằng cách sử dụng một loại chặn lib như httpclient hoặc được xây dựng trong java http công cụ, hoặc tôi nên sử dụng mới hơn không chặn io java công cụ - nó có vẻ đặc biệt phức tạp cho một cái gì đó mà nên được đơn giản.Ứng dụng HTTP không đồng bộ cho Java

Điều tôi đang tìm kiếm là điều dễ sử dụng từ quan điểm của nhà phát triển - một thứ tương tự như URLLoader trong AS3 - nơi bạn chỉ cần tạo URLRequest - đính kèm một loạt các trình xử lý sự kiện để xử lý hoàn thành, lỗi, tiến trình, vv, và gọi một phương pháp để bắn nó đi.

Nếu bạn không quen thuộc với URLLoader trong AS3, nó nên siêu dễ dàng và trông giống như sau:

private void getURL(String url) 
{ 
    URLLoader loader = new URLLoader(); 
    loader.addEventListener(Event.Complete, completeHandler); 
    loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler); 
    loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); 

    URLRequest request = new URLRequest(url); 

    // fire it off - this is asynchronous so we handle 
    // completion with event handlers 
    loader.load(request); 
} 

private void completeHandler(Event event) 
{ 
    URLLoader loader = (URLLoader)event.target; 
    Object results = loader.data; 

    // process results 
} 

private void httpStatusHandler(Event event) 
{ 
    // check status code 
} 

private void ioErrorHandler(Event event) 
{ 
    // handle errors 
} 

Trả lời

5

Hình như bạn muốn (một phần của) nio - có một hướng dẫn tốt here, các phần mạng không đồng bộ bắt đầu tại p. 30 và có nhiều liên kết hữu ích ở cuối.

1

Vì vậy, có lẽ đáng xem xét rằng ActionScript và Java không máy chủ cùng một niche. Ví dụ, Java làm cho một số thứ tẻ nhạt hơn - nhưng thường là để cung cấp cho người dùng nhiều tùy chọn hơn, ví dụ như một kết nối HTTP được thực thi, trong khi đó, ActionScript có thể trừu tượng hóa các chi tiết hoặc các lỗi có thể xảy ra. Nhưng, quan điểm của bạn vẫn đứng vững.

Bản thân tôi không nhận thức được một máy khách HTTP không đồng bộ cho Java. Câu trả lời của Alex Martelli nói về NIO của Java, một câu trả lời hay nếu bạn quan tâm đến việc triển khai giao thức HTTP trong mã của riêng bạn. NIO sẽ cho phép bạn sử dụng các ổ cắm để kết nối với máy chủ web - nhưng sau đó bạn phải tự tạo các yêu cầu GET của riêng mình và phân tích cú pháp tiêu đề/dữ liệu HTTP đến.

Một tùy chọn khác là sử dụng các lớp java.net.URL - và bạn có thể tìm thấy nhiều hướng dẫn cho những người trực tuyến và trên stackoverflow. Bạn có thể bọc chúng trong các chủ đề - vì vậy chương trình java của bạn có nhiều luồng thực thi.

Nhưng sau đó bạn gặp sự cố đồng bộ hóa. Mà tôi đồng ý, là một nỗi đau, nhưng sau đó nó cung cấp một mức độ linh hoạt chi tiết hơn.

(Tôi nhận ra rằng đây không trả lời câu hỏi của bạn - và nếu ai thực sự biết của một cơ sở java để làm yêu cầu http không đồng bộ, tôi muốn được quan tâm để biết)

+0

Hoàn toàn hiểu các hốc khác nhau. Tuy nhiên, trong trường hợp này, chúng tôi đang sử dụng Java làm khung giao diện người dùng ứng dụng khách và rất nhiều dữ liệu được trình bày đến từ các dịch vụ web bên ngoài. – helifreak

+0

Trên thực tế có nhiều ứng dụng http không đồng bộ, được liệt kê trong các câu trả lời khác (cầu cảng đã có một năm trong nhiều năm, jakarta hc khá lâu; khách hàng http không đồng bộ của ning mới nhất và tích cực phát triển). Họ chỉ không nhận được đủ sự chú ý mà họ xứng đáng được hưởng. – StaxMan

1

AFAIK công cụ TCPMon mất một cách tiếp cận tương tự với những gì bạn mô tả. Bạn có thể xem mã nguồn trong số SVN browser

Ngoài ra, hãy xem WGET-java để đảm bảo mã khóa chặn.

Nhưng bạn có phải viết điều này trong Java không? Có rất nhiều cách tiếp cận khác sử dụng JRuby hoặc Rhino để thực hiện một cái gì đó như thế này một cách dễ dàng sẽ chạy trên JVM nhưng không được viết bằng Java.

+0

Vâng, việc sử dụng các ngôn ngữ khác để biên dịch sang bytecode java là một lựa chọn trong tương lai, nhưng chúng tôi chắc chắn cũng cần một cái gì đó dựa trên Java. Cảm ơn những lời đề nghị. – helifreak

1

httpunithtmlunit là 2 khách hàng Java http tùy chỉnh và có thể định cấu hình có thể duyệt bất kỳ thứ gì như trình duyệt firefox, duyệt web không đầu, khách hàng phần mềm theo lịch trình và đại lý.

+0

Tôi sẽ đề cập đến điều này, nhưng không phải trong số này là asynch. Tuy nhiên, họ thực hiện công việc tự động hóa khá nhanh chóng. – cwash

0

Tôi khuyên bạn nên kích hoạt các chuỗi riêng biệt cho điều đó.

+0

ngay cả khi tôi đã tách các chủ đề tách biệt, tôi vẫn cảm thấy các chủ đề đang chặn và không nhanh như tôi mong đợi ... – trillions

6

Nếu bạn chưa xem nó, hãy xem Java 5 java.util.đồng thời - nó làm cho các ứng dụng đa luồng dễ phát triển hơn nhiều. Bạn có thể thiết lập một ThreadPoolExecutor quản lý, ví dụ, bốn Threads. Sau đó, bạn cấp dữ liệu cho nhóm bất kỳ số nhiệm vụ nào cần hoàn thành. Mỗi nhiệm vụ là một Runnable. ThreadPoolExecutor sẽ xếp hàng các nhiệm vụ Runnable và đưa chúng vào các Threads có sẵn song song. Phương thức afterExecute() của Pool được gọi khi mỗi nhiệm vụ Runnable hoàn tất.

Tôi nhớ rất rõ cách viết hồ sơ chuỗi tìm nạp cho trình duyệt web được viết bằng Java vào năm 1999 và đó là gấu để có quyền. Tháng trước tôi đã viết một thử nghiệm tải cho một máy chủ web. Người thử nghiệm có một ThreadPoolExecutor có n chủ đề, và các nhiệm vụ Runnable tôi nạp nó mỗi tìm nạp một trang bằng cách sử dụng Apache HTTP Client. Chỉ mất một hoặc hai giờ để nó hoạt động khá tốt. Tôi nghĩ bạn sẽ thích java.util.concurrent cùng với Apache HTTP Client, mặc dù nó có vẻ như bạn sẽ cần phải thực hiện một số tùy chỉnh cho chỉ thị tiến trình.

(Lưu ý rằng Apache HTTP khách hàng làm sợi tổng hợp riêng của mình, và cấu hình giới hạn mặc định bạn 20 đề max, và chỉ có hai cho mỗi máy chủ web).

Cập nhật: Đây là liên kết để Apache HTTP Client. Hãy chắc chắn để đọc lên trên MultiThreadedHttpConnectionManager, đó là những gì xử lý các hồ bơi kết nối, và nó không được hiển thị trong ví dụ cơ bản nhất.

+0

Thông tin tốt. Cảm ơn. Tôi vẫn không thể tin được Java khách hàng không thân thiện như thế nào. Có lẽ Java chỉ mới bắt đầu cho thấy tuổi của nó. – helifreak

+0

Tôi hầu như không phát triển Java trong suốt 1,4 năm và Java 5 năm, và bây giờ tôi thấy Java 6 tốt hơn đáng kể so với 1,3. Ngoài java.util.concurrent, generics và khung Collections nổi bật. Mặc dù vậy, công nghệ được phân lớp trên Java có vẻ không thân thiện: so sánh JAXP với xử lý XML ngắn gọn của Groovy. Cũng thế. các ngôn ngữ động như Ruby, Python và Scala là những đối thủ cạnh tranh nghiêm trọng trong những ngày này. –

+2

Không, không phải là Java đang hiển thị tuổi; hãy kiểm tra nhiều máy khách http không được chặn (không đồng bộ) không phải JDK. Không cần phải rõ ràng gây rối với chủ đề chỉ để thực hiện truy cập đồng thời. Trong khi nó sẽ là thuận tiện để có thay thế không chặn trong JDK có rất nhiều điều hữu ích mà nó có lẽ là tốt hơn để cố gắng giữ cho JDK từ ballooning bất kỳ lớn hơn. – StaxMan

0

Tôi chỉ cần stumbled khi client HTTP đồng bộ thực hiện trong Geronimo. Bạn cũng có thể muốn xem xét nó, tại http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/ - Caveat: cam kết mới nhất có vẻ hơn một tuổi.

Một dự án xây dựng một ứng dụng HTTP không đồng bộ là xsocket: xsocket.sourceforge.net

+0

http://cwiki.apache.org/AWEB/ này dường như là vị trí hiện tại. Bạn không chắc chắn hoạt động của nó như thế nào. – Eelco

8

Phiên bản 4.0 của Apache Commons HttpClient (hiện tại trong HttpComponents/HttpCore) cũng hỗ trợ NIO của Java (không chặn IO). Tôi nghĩ rằng đây là đặt cược tốt nhất của bạn.

15

Sử dụng "Ứng dụng khách Async Http" trước đây được gọi là thư viện máy khách http ning. Xem http://code.ning.com/2010/03/introducing-nings-asynchronous-http-client-library/

Bây giờ trống trong GitHub https://github.com/ning/async-http-client

+1

Và nó ở github tại http://github.com/ning/async-http-client. Tôi có thể đề xuất điều này, đã sử dụng nó, mặc dù chủ yếu chỉ là một ứng dụng http đồng bộ đáng tin cậy đơn giản. Nhưng với các kết quả đơn giản trong tương lai, hoạt động async rất đơn giản để sử dụng. – StaxMan

+1

Họ đã thay đổi bản repo của GitHub, hiện tại họ đang ở http://github.com/AsyncHttpClient/async-http-client – jfager

+1

Họ thực sự đã thay đổi lại GitHub repos và bây giờ là https://github.com/sonatype/ async-http-client. Tôi đã cập nhật câu trả lời để phản ánh đúng vị trí repo ngay bây giờ. –

2

có thư viện và các khung văn bản trên đầu trang của nio/Netty - RxNettyVertx mà có thể hữu ích để viết không đồng bộ HTTP client

Dưới đây là một ví dụ mã sử dụng Vertx

public class Client extends AbstractVerticle { 

    @Override 
    public void start() throws Exception { 
    //lambda callback would be called when the response comes back 
    vertx.createHttpClient().getNow(8080, "localhost", "/", resp -> { 
     System.out.println("Got response " + resp.statusCode()); 
     resp.bodyHandler(body -> { 
     System.out.println("Got data " + body.toString("ISO-8859-1")); 
     }); 
    }); 
    //this code statement will execute before response comes back 
    System.out.println("I am not blocked"); 
    } 
} 

bạn có thể tìm thấy đầy đủ thổi mã ví dụ từ here

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