是否可以在Actor内部发出Akka HTTP核心客户端请求?

时间:2015-08-27 03:47:26

标签: scala akka akka-http

下面是一个简单的actor,需要进行HTTP调用才能从API接收数据。根据{{​​3}},只需隐式ActorSystemActorMaterializer

class MyActor extends Actor {

  import context.system
  implicit val materializer = ActorMaterializer()

  override def receive: Receive = {
    case _ => {
      val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http://akka.io"))
      responseFuture onComplete {
        case Success(res) => println(res)
        case Failure(t) => println("An error has occured: " + t.getMessage)
      }
    }
  }
}

但是,在尝试编译应用程序时,我收到以下错误消息:

Error:(18, 48) ambiguous implicit values: both value context in trait Actor of type => akka.actor.ActorContext and method system in trait ActorContext of type => akka.actor.ActorSystem match expected type akka.actor.ActorRefFactory
  implicit val materializer = ActorMaterializer()

Error:(18, 48) implicit ActorRefFactory required: if outside of an Actor you need an implicit ActorSystem, inside of an actor this should be the implicit ActorContext
  implicit val materializer = ActorMaterializer()

Error:(18, 48) not enough arguments for method apply: (implicit context: akka.actor.ActorRefFactory)akka.stream.ActorMaterializer in object ActorMaterializer. Unspecified value parameter context.
  implicit val materializer = ActorMaterializer()

Error:(22, 70) could not find implicit value for parameter fm: akka.stream.Materializer 
  val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http://akka.io"))

Error:(22, 70) not enough arguments for method singleRequest: (implicit fm: akka.stream.Materializer)scala.concurrent.Future[akka.http.scaladsl.model.HttpResponse]. Unspecified value parameter fm.
  val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http://akka.io"))

Error:(23, 22) Cannot find an implicit ExecutionContext. You might pass an (implicit ec: ExecutionContext) parameter to your method or import scala.concurrent.ExecutionContext.Implicits.global.
  responseFuture onComplete {

Error:(23, 22) not enough arguments for method onComplete: (implicit executor: scala.concurrent.ExecutionContext)Unit. Unspecified value parameter executor.
  responseFuture onComplete {

这是在Akka Actor中进行HTTP调用的正确方法吗?

修改

包含import ExecutionContext.Implicits.global以修复最后两个ExecutionContext错误。

1 个答案:

答案 0 :(得分:11)

创建ActorMaterializer需要隐式的ActorRefFactory。 Actor trait中定义的context属性扩展了ActorRefFactory,它是隐式的。显式导入的上下文系统属性是ActorRefFactory的另一个隐式候选者,因为ActorSystem扩展了ActorRefFactory。

我的建议是删除导入并将其明确传递到需要的位置。

class MyActor extends Actor {

  // Do not import context.system
  // import context.system
  implicit val materializer = ActorMaterializer()

  override def receive: Receive = {
    case _ => {
      // use context.system explicitly
      val responseFuture: Future[HttpResponse] = Http(context.system)
        .singleRequest(HttpRequest(uri = "http://akka.io"))
      responseFuture onComplete {
        case Success(res) => println(res)
        case Failure(t) => println("An error has occured: " + t.getMessage)
      }
    }
  }
}