2013-05-03 13 views
5

Tutti,AsyncHttpClient può eseguire chiamate HTTP asincrone e non bloccanti?

Sto cercando di decidere se utilizzare NodeJS o Java per la mia applicazione. Comunicherò con CouchDB via HTTP e vorrei un progetto asincrono non bloccante in cui il thread dell'applicazione può elaborare richieste aggiuntive mentre attende la risposta alla query da CouchDB.

Preferirei usare Java e ho cercato AsyncHttpClient per alcuni giorni come soluzione potenziale. Tuttavia, sto avendo qualche problema a capire la biblioteca e penso che possa avere un fondamentale fraintendimento di qualcosa.

Ho pubblicato un succo qui: "Richiesta X mandato" https://gist.github.com/conorgil/5505603

mi aspetterei questo nocciolo per stampare AND "Risposta X: qualcosa" per ogni richiesta. Tuttavia, sembra che la chiamata HTTP non sia stata effettuata (e quindi il gestore non è stato eseguito) fino a quando Future non chiama get(). La riga non compromettente 23 f.get() fa funzionare il codice come previsto, ma la chiamata a Future # get() sta bloccando, corretta? C'è un modo per fornire semplicemente una funzione di callback che viene eseguita una volta che la risposta HTTP è stata completamente recuperata senza bloccare?

qualcosa quanto segue: 1) richiesta arriva sul filo principale 2) asincrona non bloccante chiamata HTTP è finalizzata CouchDB. Un gestore di completamento è registrato per elaborare la risposta da CouchDB 3) il thread principale è ora libero di elaborare la richiesta successiva 4) La risposta HTTP da CouchDB arriva ad un certo punto e il gestore registrato viene chiamato per eseguire alcune logiche di business 5) thread principale continua solo le richieste di elaborazione (per le richieste che non hanno bisogno di colpire CouchDB, possono essere risposto molto rapidamente)

Sono fondamentalmente frainteso qualcosa qui? È possibile fare questo tipo di cose in Java? AsyncHttpClient è la risposta? Questa domanda è correlata, ma non è sicuro se le cose sono cambiate da quando 2011 (Perform Async Connect with Java AsyncHttpClient Library?)

Dal NodeJS esegue un ciclo di eventi, questo non bloccante, il comportamento asincrono è di serie. Dovresti semplicemente registrare una funzione di callback per gestire la risposta del DB quando è stata ricevuta e il ciclo degli eventi elaborerebbe solo altre cose nel frattempo.

Qualsiasi consiglio è apprezzato.

Grazie, Conor

+0

Sì, lo è. Date un'occhiata a vert.x –

+0

node.js è abbastanza decente come un leggero proxy/gateway inverso con logica di app minore con couchdb semplicemente a causa dell'interfaccia http del divano e del semplice nodo asincrono http del nodo. Java è più performante per la logica dell'app pesante. –

risposta

0

Nel caso in cui si può migliorare il server HTTP DB per supportare richiesta asincrona, allora vi suggerisco di farlo.

Generalmente le richieste Async Http vengono implementate utilizzando RICHIESTA INVIA-> RICHIESTA ACCETTATA-> LAVORO POLLING -> RISPOSTA DI LAVORO.

richiesta

Asyn sono realizzati tramite POST/PUT in cui si invia una richiesta e si ottiene 202 accettato con un URL di polling nell'intestazione HTTP per ottenere il risultato in modo asincrono. Ora puoi eseguire il polling per ottenere il risultato, se il risultato è disponibile dovresti ottenere 200 OK con qualche risultato come xml/json/output di testo altrimenti potresti ricevere il codice HTTP di errore come 503 Servizio non disponibile.

2

Lo scopo principale di AsyncHttpClient è HTTP non bloccante e l'ho utilizzato con successo in questo senso. Ad esempio, ho eseguito questa versione semplificata del codice:

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

Avviso nessun futuro è coinvolto.Produce il seguente output, proprio come ci si dovrebbe aspettare:

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> 

... 

L'unico problema è, il processo viene lasciato appeso, perché non esiste un codice che spegne il cliente, ma questa è una storia a parte.

Problemi correlati