在Spray路线中呼叫演员并等待演员的回应

时间:2014-10-11 11:00:04

标签: scala akka actor spray

使用Play之后!框架一段时间,我先看看Spray。我从我在GitHub上找到的一个样本开始,现在我想修改它但是我不容易理解它是如何工作的。

如何在下面的代码中等待来自Actor的消息?

package api

import akka.actor.ActorRef
import scala.concurrent.ExecutionContext
import spray.routing.Directives
import core.ClassifierActor

class ClassifierService(classifier: ActorRef)(implicit executionContext: ExecutionContext)
  extends Directives with DefaultJsonFormats {

  import ClassifierActor._

  implicit val classifyMessageFormat = jsonFormat4(ClassifyMessage)

  val route =
    path("classify") {
      post {
        handleWith { 
          // The ClassifierActor gets a ClassifyMessage and 
          // sends a ClassifiedMessage back to the sender.
          // How can wait for the ClassifiedMessage here 
          // and send a HttpResponse back?
          cm: ClassifyMessage => classifier ! cm
          // ???
        }
      }
    }

}

2 个答案:

答案 0 :(得分:13)

Spray已基于akka.io

因此,如果您只想通过演员回应完成路线,可以使用询问模式

import akka.pattern.ask  
import scala.concurrent.duration._
implicit val timeout = Timeout(5 seconds) // needed for `?` below

 val route =
    path("classify") {
      post {
        onComplete(actorResponse(yourActor, yourMessage)) {
          complete(_)
        }
      }
    }

def actorResponse[T](actor: ActorRef, msg: ClassifyMessage): Future[T] = 
(actor ? msg).mapTo[T]

如果要将请求转发给actor模型并在actor系统中的某个地方完成路由,则需要将RequestContext转发给actor。也许,这example可以帮到你。祝你好运!

答案 1 :(得分:3)

看看我的示例项目。 This service使用Futures完成路线。像Rup评论的那样,等待回应是不好的做法。立即返回未来,并在得到结果时让它完成。

在您的示例中classifier ! cm正在使用actor“tell”模式。它向cm演员发送消息classifier并继续前进。如果您希望将来回复,请使用“ask”模式:classifier ? cm。在cm演员的接收方法中,您将返回sender ! responseMsg的未来,将来会返回。