2013-05-03 5 views
5

Alle,kann AsyncHttpClient nicht blockierende asynchrone HTTP-Aufrufe ausführen?

Ich versuche zu entscheiden, ob ich NodeJS oder Java für meine Anwendung verwenden soll. Ich werde mit CouchDB über HTTP kommunizieren und möchte ein asynchrones, nicht blockierendes Design, bei dem mein Anwendungsthread zusätzliche Anforderungen verarbeiten kann, während er auf die Abfrageantwort von CouchDB wartet.

Ich würde lieber Java verwenden und ich habe AsyncHttpClient für ein paar Tage als eine mögliche Lösung betrachtet. Allerdings habe ich einige Schwierigkeiten, die Bibliothek zu verstehen und denke, dass ich ein grundlegendes Missverständnis von etwas habe.

gepostet ich einen Kern hier: https://gist.github.com/conorgil/5505603

ich diesen Kern auszudrucken erwarten würde „gesendet anfordern X!“ UND "Antwort X: etwas" für jede Anfrage. Es scheint jedoch, dass der HTTP-Aufruf nicht gemacht wird (und somit der Handler nicht ausgeführt wird), bis jeder Future get() aufruft. Das Unterkommentieren von Zeile 23 f.get() lässt den Code wie erwartet funktionieren, aber der Aufruf von Future # get() blockiert, richtig? Gibt es eine Möglichkeit, eine Callback-Funktion bereitzustellen, die ausgeführt wird, sobald die HTTP-Antwort vollständig abgerufen wurde, ohne zu blockieren?

So etwas wie das Folgende: 1) Anfrage kommt auf Hauptthread 2) asynchronen, nicht blockierenden HTTP-Anruf wird an CouchDB gemacht. Ein Completion-Handler registriert die Antwort von CouchDB 3) Der Haupt-Thread kann jetzt die nächste Anfrage bearbeiten 4) Die HTTP-Antwort von CouchDB kommt irgendwann und der registrierte Handler wird aufgerufen, um eine Geschäftslogik auszuführen. 0) main thread fährt nur mit der Verarbeitung von Anfragen fort (für Anfragen, die nicht auf CouchDB treffen müssen, können sie sehr schnell beantwortet werden)

Bin ich hier grundsätzlich falsch? Ist es möglich, diese Art von Sache in Java zu tun? Ist AsyncHttpClient die Antwort? Diese Frage hängt zusammen, ist aber nicht sicher, ob sich die Dinge seit 2011 geändert haben. (Perform Async Connect with Java AsyncHttpClient Library?)

Da NodeJS eine Ereignisschleife ausführt, ist dieses nicht blockierende asynchrone Verhalten Standard. Sie würden einfach eine Callback-Funktion registrieren, um die DB-Antwort zu behandeln, wenn sie empfangen wurde, und die Ereignisschleife würde in der Zwischenzeit nur andere Dinge verarbeiten.

Alle und alle Ratschläge sind willkommen.

Danke, Conor

+0

Ja ist es. Werfen Sie einen Blick auf vert.x –

+0

node.js ist ziemlich anständig als ein leichtes Reverse-Proxy/Gateway mit geringer App-Logik mit couchdb einfach wegen Couch http-Schnittstelle und Knoten ist einfach async http gebacken in. Java ist performativer für schwere App-Logik. –

Antwort

0

Falls Sie Ihre DB HTTP-Server verbessern können Async Anforderung zu unterstützen, dann werde ich dies zu tun vorschlagen.

Im Allgemeinen werden Http Async-Anfragen mit REQUEST SUBMIT-> REQUEST ACCEPTED-> JOB POLLING -> JOB RESPONSE implementiert.

Asyn-Anfrage wird mithilfe von POST/PUT implementiert, wo Sie eine Anfrage senden, und Sie erhalten 202 Accepted zusammen mit einer Abruf-URL im HTTP-Header, um das Ergebnis asynchron zu erhalten. Jetzt können Sie dies abfragen, um das Ergebnis zu erhalten. Wenn das Ergebnis verfügbar ist, sollten Sie 200 OK mit einem Ergebnis als xml/json/text-Ausgabe erhalten, andernfalls erhalten Sie möglicherweise einen HTTP-Fehlercode wie 503 Service nicht verfügbar.

2

Der Hauptzweck von AsyncHttpClient ist nicht blockierende HTTP und ich habe es erfolgreich zu diesem Zweck verwendet. Zum Beispiel habe ich diese vereinfachte Version Ihres Codes ausgeführt:

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

Beachten Sie, dass keine Futures beteiligt sind.Es erzeugt die folgende Ausgabe, so wie man erwarten sollte:

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> 

... 

Das einzige Problem ist, wird der Prozess hängen gelassen, weil es keinen Code, der den Client heruntergefahren, aber das ist eine separate Geschichte.

Verwandte Themen