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

Dav*_*ria 7 scala akka akka-http

下面是一个简单的actor,它需要进行HTTP调用以从API接收数据.根据Akka HTTP核心请求级客户端API,只需隐式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)
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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 {
Run Code Online (Sandbox Code Playgroud)

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

编辑

包括import ExecutionContext.Implicits.global修复最后两个ExecutionContext错误.

thi*_*row 12

An implicit ActorRefFactory is required to create the ActorMaterializer. The context property defined in the Actor trait extends ActorRefFactory, and it's implicit. The system property on context, which you imported explicitly, is another implicit candidate for ActorRefFactory, because ActorSystem extends ActorRefFactory.

My suggestion is removing the import and passing it explicitly where it is needed.

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)
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)