2013-05-03 21 views
5

Wszystko,Czy AsyncHttpClient może wykonywać nieblokujące, asynchroniczne wywołania HTTP?

Próbuję podjąć decyzję, czy użyć aplikacji NodeJS lub Java dla mojej aplikacji. Będę komunikował się z CouchDB przez HTTP i chciałbym asynchronicznego nieblokującego się projektu, w którym mój wątek aplikacji może przetwarzać dodatkowe żądania podczas oczekiwania na odpowiedź zapytania z CouchDB.

Wolałbym używać Javy i szukałem AsyncHttpClient przez kilka dni jako potencjalne rozwiązanie. Mam jednak problem ze zrozumieniem biblioteki i myślę, że mogę mieć fundamentalne niezrozumienie czegoś.

Zamieściłem tu sedno: „Wniosek wysłany X” https://gist.github.com/conorgil/5505603

spodziewałbym to sens, aby wydrukować ORAZ "Odpowiedź X: coś" dla każdego żądania. Wygląda jednak na to, że wywołanie HTTP nie jest wykonywane (a zatem program obsługi nie jest wykonywany), dopóki wszystkie przyszłe wywołania get(). Uncommenting linii 23 f.get() sprawia, że ​​kod działa zgodnie z oczekiwaniami, ale wywołanie Future # get() jest blokowanie, prawda? Czy istnieje sposób, aby po prostu dostarczyć funkcję zwrotną, która zostanie wykonana po uzyskaniu pełnej odpowiedzi HTTP bez blokowania?

Coś jak poniżej: 1) żądanie przychodzi w głównym wątku 2) asynchroniczne, nieblokujące wywołanie HTTP jest wykonywane w CouchDB. Procedura obsługi zakończyła rejestrację w celu przetworzenia odpowiedzi z CouchDB 3) główny wątek może teraz przetworzyć następne żądanie: 4) Odpowiedź HTTP z CouchDB pojawia się w pewnym momencie, a zarejestrowany handler jest wywoływany w celu wykonania logiki biznesowej 5) główny wątek kontynuuje tylko przetwarzanie żądań (dla żądań, które nie muszą uderzać w CouchDB, mogą być szybko reagowane)

Czy zasadniczo coś tutaj nie rozumiem? Czy można robić tego typu rzeczy w Javie? Czy AsyncHttpClient jest odpowiedzią? To pytanie jest powiązane, ale nie jest pewne, czy sytuacja zmieniła się od 2011 (Perform Async Connect with Java AsyncHttpClient Library?)

Ponieważ NodeJS uruchamia pętlę zdarzeń, to nieblokujące zachowanie asynchroniczne jest standardem. Wystarczy zarejestrować funkcję wywołania zwrotnego, aby obsłużyć odpowiedź DB, gdy została ona odebrana, a pętla zdarzeń po prostu przetworzy w międzyczasie inne rzeczy.

Wszelkie rady są mile widziane.

Dzięki Conor

+0

Tak jest. Spójrz na vert.x –

+0

node.js jest całkiem przyzwoity jako lekki odwrotny serwer proxy/brama z niewielką logiką aplikacji z couchdb po prostu z powodu interfejsu http na kanapie i łatwego asynchronicznego http węzła w węźle. Java jest bardziej wydajna dla ciężkiej logiki aplikacji. –

Odpowiedz

0

W przypadku można poprawić swój serwer http DB wspierać wniosek Async wtedy proponuję zrobić.

Generalnie żądania asynchroniczne Http są realizowane za pomocą ŻĄDANIA ZAPYTAŃ-> ŻĄDANIE AKCEPTOWANE-> ZAPYTANIE OFERTOWE -> ODPOWIEDŹ PRACY.

Żądanie Asyn są realizowane za pomocą POST/PUT, gdzie przesłać żądanie, a otrzymasz 202 akceptowane wraz z adresem URL odpytywania w nagłówku HTTP, aby uzyskać wynik asynchronicznie. Teraz możesz sondować to, aby uzyskać wynik, jeśli wynik jest dostępny, powinieneś uzyskać 200 OK z pewnym wynikiem jako xml/json/tekst wyjściowy w przeciwnym razie możesz uzyskać błąd kodu HTTP, taki jak 503 Usługa niedostępna.

2

Głównym celem AsyncHttpClient jest nieblokujący się protokół HTTP i z powodzeniem wykorzystałem go w tym celu. Na przykład uruchomiłem tę uproszczoną wersję Twojego kodu:

public class MyAsyncHttpClientTest { 
    public static void main(String[] args) throws Exception { 
    AsyncHttpClient asyncHttpClient = new AsyncHttpClient(); 
    for (int i = 0; i < 10; i++) { 
     asyncHttpClient.prepareGet("http://www.google.com") 
     .execute(new CompletionHandler(i)); 
     System.out.println(String.format("Request %d sent! ", i)); 
     System.out.flush(); 
    } 
    } 
    static class CompletionHandler extends AsyncCompletionHandler<Void> { 
    private final int reqNumber; 
    public CompletionHandler(int reqNumber) { this.reqNumber = reqNumber; } 
    @Override public Void onCompleted(Response response) throws Exception { 
     System.out.println(String.format("Response %d: %s", reqNumber, 
      response.getResponseBody())); 
     return null; 
    } 
    } 
} 

Zawiadomienie o braku kontraktów futures.To daje następujące dane wyjściowe, jak należy się spodziewać:

Request 0 sent! 
Request 1 sent! 
Request 2 sent! 
Request 3 sent! 
Request 4 sent! 
Request 5 sent! 
Request 6 sent! 
Request 7 sent! 
Request 8 sent! 
Request 9 sent! 
Response 1: <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"> 
<TITLE>302 Moved</TITLE></HEAD><BODY> 
<H1>302 Moved</H1> 
The document has moved 
<A HREF="http://www.google.hr/">here</A>. 
</BODY></HTML> 

Response 0: <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"> 
<TITLE>302 Moved</TITLE></HEAD><BODY> 
<H1>302 Moved</H1> 
The document has moved 
<A HREF="http://www.google.hr/">here</A>. 
</BODY></HTML> 

... 

Jedynym problemem jest to, proces zostaje powieszenie, ponieważ nie ma kodu, który wyłącza klienta, ale to osobna historia.