2015-06-19 11 views
5

Szukamy możliwości korzystania z API Java API Akka-HTTP za pomocą Routing DSL.Jak zareagować na wynik wywołania aktora?

Nie jest jasne, jak korzystać z funkcji Routing, aby odpowiedzieć na żądanie HttpRequest; przy użyciu nieślubnego akka aktora. Na przykład po dopasowaniu ścieżki trasy, w jaki sposób przekazujemy żądanie do "podmiotu obsługi" ActorRef, który następnie odpowie HttpResponse w sposób asynchroniczny?

Podobne pytanie zostało zamieszczone na liście mailingowej Akka-User, ale bez żadnych rozwiązań uzupełniających jako takie - https://groups.google.com/d/msg/akka-user/qHe3Ko7EVvg/KC-aKz_o5aoJ.

Odpowiedz

5

Można to osiągnąć za pomocą kombinacji dyrektywy onComplete i wzoru ask.

W poniższym przykładzie aktor RequestHandlerActor jest używany do tworzenia HttpResponse w oparciu o HttpRequest. Ten aktor jest pytany z poziomu trasy.

Nigdy nie używał Java do kodowania trasy, więc moja odpowiedź jest w 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}")) 
    } 
    } 

Droga ta może być następnie wykorzystana przekazywane do metody jak każdy inny przepływu bindAndHandle.

1

Szukałem rozwiązania tego samego problemu, który opisał autor pytania. W końcu doszedłem do następującego kodu Java do tworzenia trasy:

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

I RequestHandlerActor jest:

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); 
     } 
    } 
} 
Powiązane problemy