2015-06-19 14 views
5

Chúng tôi đang xem xét sử dụng API Java Akka-HTTP - sử dụng Định tuyến DSL.Cách phản hồi với kết quả của cuộc gọi diễn viên?

Không rõ cách sử dụng chức năng Định tuyến để phản hồi một HttpRequest; sử dụng diễn viên Akka Untyped. Ví dụ, khi kết hợp một đường dẫn Route, làm thế nào để chúng ta đưa ra yêu cầu tới một "handler" ActorRef, sau đó nó sẽ phản hồi với một HttpResponse theo cách không đồng bộ?

Câu hỏi tương tự đã được đăng trên danh sách gửi thư của người dùng Akka, nhưng không có giải pháp theo dõi như vậy - https://groups.google.com/d/msg/akka-user/qHe3Ko7EVvg/KC-aKz_o5aoJ.

Trả lời

5

Điều này có thể được thực hiện bằng cách kết hợp chỉ thị onComplete và mẫu ask.

Trong ví dụ dưới đây, diễn viên RequestHandlerActor được sử dụng để tạo một HttpResponse dựa trên HttpRequest. Nam diễn viên này được hỏi từ bên trong tuyến đường.

Tôi chưa bao giờ sử dụng Java cho mã định tuyến để phản hồi của tôi ở 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}")) 
    } 
    } 

Tuyến đường này sau đó có thể được sử dụng được chuyển vào phương pháp bindAndHandle như bất kỳ luồng nào khác.

1

Tôi đã tìm giải pháp cho cùng một vấn đề như được mô tả bởi tác giả của câu hỏi. Cuối cùng, tôi đã đưa ra để mã Java sau để tạo tuyến đường:

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 là:

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); 
     } 
    } 
} 
Các vấn đề liên quan