Как ответить результатом звонка актера?

Мы рассматриваем использование Akka-HTTP Java API - использование Routing DSL.

Непонятно, как использовать функцию маршрутизации для ответа на HttpRequest; с использованием нетипизированного актера Akka. Например, после сопоставления пути маршрута, как передать запрос «обработчику» ActorRef, который затем ответит HttpResponse асинхронным способом?

Аналогичный вопрос был размещен в списке рассылки Akka-User, но без дополнительных решений как таковых - https://groups.google.com/d/msg/akka-user/qHe3Ko7EVvg/KC-aKz_o5aoJ.


person Piyush Jajoo    schedule 19.06.2015    source источник


Ответы (2)


Этого можно добиться с помощью комбинации _ 1_ и спросить.

В приведенном ниже примере субъект RequestHandlerActor используется для создания HttpResponse на основе HttpRequest. Этого Актера спрашивают из маршрута.

Я никогда не использовал Java для кода маршрутизации, поэтому мой ответ на Scala.

import scala.concurrent.duration._
import akka.actor.ActorSystem
import akka.http.scaladsl.model.HttpResponse
import akka.http.scaladsl.model.HttpRequest
import akka.actor.Actor
import akka.http.scaladsl.server.Directives._
import akka.actor.Props
import akka.pattern.ask
import akka.util.Timeout
import scala.util.{Success, Failure}
import akka.http.scaladsl.model.StatusCodes.InternalServerError

class RequestHandlerActor extends Actor {
  override def receive = {
    case httpRequest : HttpRequest =>
      sender() ! HttpResponse(entity = "actor responds nicely")
  }
}

implicit val actorSystem = ActorSystem()
implicit val timeout = Timeout(5 seconds)

val requestRef = actorSystem actorOf Props[RequestHandlerActor]

val route = 
  extractRequest { request =>
    onComplete((requestRef ? request).mapTo[HttpResponse]) {
      case Success(response) => complete(response)
      case Failure(ex) => 
        complete((InternalServerError, s"Actor not playing nice: ${ex.getMessage}"))
    } 
  }

Затем этот маршрут можно использовать для передачи в bindAndHandle как и любой другой Flow.

person Ramón J Romero y Vigil    schedule 17.01.2016

Я искал решение той же проблемы, которую описал автор вопроса. Наконец, я подошел к следующему коду Java для создания маршрута:

    ActorRef ref = system.actorOf(Props.create(RequestHandlerActor.class));

    return get(() -> route(
            pathSingleSlash(() ->
                    extractRequest(httpRequest -> {
                        Timeout timeout = new Timeout(Duration.create(5, TimeUnit.SECONDS));
                        CompletionStage<HttpResponse> completionStage = PatternsCS.ask(ref, httpRequest, timeout)
                                .thenApplyAsync(HttpResponse.class::cast);

                        return completeWithFuture(completionStage);
                    })
            ))
    );

И RequestHandlerActor это:

public class RequestHandlerActor extends UntypedActor {
    @Override
    public void onReceive(Object msg) {
        if (msg instanceof HttpRequest) {
            HttpResponse httpResponse = HttpResponse.create()
                    .withEntity(ContentTypes.TEXT_HTML_UTF8,
                            "<html><body>Hello world!</body></html>");

            getSender().tell(httpResponse, getSelf());
        } else {
            unhandled(msg);
        }
    }
}
person tysonite    schedule 01.11.2016