Java example for sending non-blocking http request

2020-06-23 09:12发布

问题:

It is in AKKA documentation written that

... Actors should not block (i.e. passively wait while occupying a Thread) on some external entity, which might be a lock, a network socket, etc. The blocking operations should be done in some special-cased thread which sends messages to the actors which shall act on them. source http://doc.akka.io/docs/akka/2.0/general/actor-systems.html#Actor_Best_Practices

I have found the following information at the moment :

  1. I read Sending outbound HTTP request from Akka / Scala and checked the example at https://github.com/dsciamma/fbgl1

  2. I found following article http://nurkiewicz.blogspot.de/2012/11/non-blocking-io-discovering-akka.html explaining how to use https://github.com/AsyncHttpClient/async-http-client non blocking http client with akka. But is written in Scala.

How can i write an actor that make non-blocking http requests?

It must downlad a remote url page as file and than send the generated file object to the master actor. master actor then sends this request to parser actor to parse the file...

回答1:

In the last response, Koray is using a wrong reference for the sender, the correct way to do it is:

public class ReduceActor extends UntypedActor {

@Override
public void onReceive(Object message) throws Exception {
    if (message instanceof URI) {
        URI url = (URI) message;


        AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
        final ActorRef sender = getSender();
        asyncHttpClient.prepareGet(url.toURL().toString()).execute(new AsyncCompletionHandler<Response>() {

            @Override
            public Response onCompleted(Response response) throws Exception {
                File f = new File("e:/tmp/crawler/" + UUID.randomUUID().toString() + ".html");
                // Do something with the Response
                // ...
                // System.out.println(response1.getStatusLine());
                FileOutputStream fao = new FileOutputStream(f);
                IOUtils.copy(response.getResponseBodyAsStream(), fao);
                System.out.println("File downloaded " + f);
                sender.tell(new WordCount(f));
                return response;
            }

            @Override
            public void onThrowable(Throwable t) {
                // Something wrong happened.
            }
        });
    } else
        unhandled(message);
  }

Checkout this other thread of akka: https://stackoverflow.com/a/11899690/575746



回答2:

I have implemented this in this way.

public class ReduceActor extends UntypedActor {
@Override
public void onReceive(Object message) throws Exception {
    if (message instanceof URI) {
        URI url = (URI) message;

        AsyncHttpClient asyncHttpClient = new AsyncHttpClient();

        asyncHttpClient.prepareGet(url.toURL().toString()).execute(new AsyncCompletionHandler<Response>() {

            @Override
            public Response onCompleted(Response response) throws Exception {
                File f = new File("e:/tmp/crawler/" + UUID.randomUUID().toString() + ".html");
                // Do something with the Response
                // ...
                // System.out.println(response1.getStatusLine());
                FileOutputStream fao = new FileOutputStream(f);
                IOUtils.copy(response.getResponseBodyAsStream(), fao);
                System.out.println("File downloaded " + f);
                getSender().tell(new WordCount(f));
                return response;
            }

            @Override
            public void onThrowable(Throwable t) {
                // Something wrong happened.
            }
        });
    } else
        unhandled(message);
}


标签: java akka