2015-06-19 15 views
5

Routing DSL kullanarak Akka-HTTP Java API'yi kullanıyoruz.Bir aktör çağrısının sonucuyla nasıl yanıt verilir?

Bir HttpRequest'e yanıt vermek için Yönlendirme işlevinin nasıl kullanılacağı açık değildir; Bir Untyped Akka Aktör kullanarak. Örneğin, bir Rota yolunu eşleştirdikten sonra, isteği bir "Handler" ActorRef'e nasıl teslim edeceğiz, bu da daha sonra bir HttpResponse ile eşzamansız bir şekilde yanıt verecek?

Benzer bir soru Akka Kullanıcı e-posta listesine kaydedildi, ancak hiçbir takip çözümüne sahip olmadı - https://groups.google.com/d/msg/akka-user/qHe3Ko7EVvg/KC-aKz_o5aoJ.

cevap

5

Bu, onComplete yönergesinin ve ask modelinin bir kombinasyonu ile gerçekleştirilebilir.

Aşağıdaki örnekte RequestHandlerActor aktörü HttpRequest temel alınarak HttpResponse oluşturmak için kullanılır. Bu Oyuncu rotanın içinden sorulur.

Hiçbir zaman yönlendirme kodu için Java kullanmıyorum, bu yüzden yanıtım Scala'da.

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

Bu yol, herhangi bir başka akış gibi bindAndHandle yönteme geçirilen kullanılabilir.

1

Sorunun yazarı tarafından açıklanan aynı soruna çözüm arıyorum.

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

Ve RequestHandlerActor geçerli::

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); 
     } 
    } 
} 
Son olarak, rota oluşturulması için aşağıdaki Java kodu geldi