Akka Http:在TypedActor实现方法之外调用TypedActor.context

huangapple go评论57阅读模式
英文:

Akka Http: Calling TypedActor.context outside of a TypedActor implementation method

问题

这是我的代码:

trait HttpServer {
   def sendAndReceive: HttpRequest => Future[HttpResponse]
}

trait ApiHandler extends HttpServer {
  implicit def as: ActorSystem
  override def sendAndReceive: HttpRequest => Future[HttpResponse] =
     Http().singleRequest(_)
 }

trait Api {
    this: ApiHandler =>

    implicit def as: ActorSystem
    implicit def mat: Materializer
    implicit def ec: ExecutionContext

    def request(httpRequest: HttpRequest): Future[HttpResponse] = {
      sendAndReceive(httpRequest).flatMap { response =>
         response.status match {
           case StatusCodes.OK => Future.successful(response)
           case _ => throw new RuntimeException ("error")
        }
      }
    }
  }

  class ApiImpl() (implicit val as: ActorSystem, val mat: Materializer, val ec: ExecutionContext) extends Api with ApiHandler {
       def request: Future[HttpResponse] = {
       val httpRequest = ???
       request(httpRequest)
       }
   }

这是我如何调用request方法的方式:

implicit val actorSystem = ActorSystem("system")
implicit val executionContext = actorSystem.dispatcher
implicit val materializer = ActorMaterializer()

val api = new ApiImpl()
api.request

在 trait Api 的 request 方法调用 sendAndReceive 方法时,我收到以下错误(在此行发生:sendAndReceive(httpRequest).flatMap { response => ):

Calling TypedActor.context outside of a TypedActor implementation method!

我做错了什么?

英文:

I'm trying to build akka http client, by using this example Test akka http client

This is my code:

trait HttpServer {
   def sendAndReceive: HttpRequest => Future[HttpResponse]
}

trait ApiHandler extends HttpServer {
  implicit def as: ActorSystem
  override def sendAndReceive: HttpRequest => Future[HttpResponse] =
     Http().singleRequest(_)
 }

trait Api {
    this: ApiHandler =>

    implicit def as: ActorSystem
    implicit def mat: Materializer
    implicit def ec: ExecutionContext

    def request(httpRequest: HttpRequest): Future[HttpResponse] = {
      sendAndReceive(httpRequest).flatMap { response =>
         response.status match {
           case StatusCodes.OK => Future.successful(response)
           case _ => throw new RuntimeException ("error")
        }
      }
    }
  }

  class ApiImpl() (implicit val as: ActorSystem, val mat: Materializer, val ec: ExecutionContext) extends Api with ApiHandler {
       def request: Future[HttpResponse] = {
       val httpRequest = ???
       request(httpRequest)
       }
   }

And this is how I call request method:

  implicit val actorSystem = ActorSystem("system")
  implicit val executionContext = actorSystem.dispatcher
  implicit val materializer = ActorMaterializer()

  val api = new ApiImpl()
  api.request

I receive the following error in place, where trait Api request calls sendAndReceive-method (in this line: sendAndReceive(httpRequest).flatMap { response => ):

Calling TypedActor.context outside of a TypedActor implementation method!

What am I doing wrong?

答案1

得分: 1

以下是代码的翻译部分:

trait HttpServer {
    def sendAndReceive: HttpRequest => Future[HttpResponse]
}

trait ApiHandler extends HttpServer {
    implicit def as: ActorSystem

    override def sendAndReceive: HttpRequest => Future[HttpResponse] =
        Http().singleRequest(_)
}

trait Api {
    this: ApiHandler =>

    implicit def as: ActorSystem

    implicit def mat: Materializer

    implicit def ec: ExecutionContext

    def request(httpRequest: HttpRequest) = {
        sendAndReceive(httpRequest).flatMap {
            response =>
                response.status match {
                    case StatusCodes.OK => Future.successful(response)
                    case _ => throw new RuntimeException("error")
                }
        }
    }
}

class ApiImpl()(implicit val as: ActorSystem, val mat: Materializer, val ec: ExecutionContext) extends Api with ApiHandler {
    def request2 = {
        val httpRequest = Get("https://akka.io")
        request(httpRequest)
    }
}

def main(args: Array[String]): Unit = {
    implicit val actorSystem = ActorSystem("system")
    implicit val executionContext = actorSystem.dispatcher
    implicit val materializer = ActorMaterializer()

    val api = new ApiImpl()
    api.request2.map(println(_))
}

版本信息:

val akkaVersion = "2.6.7"
val akkaHttpVersion = "10.1.12"

正常工作的输出:

HttpResponse(200 OK,List(Date: Mon, 06 Feb 2023 12:19:39 GMT, Connection: keep-alive, Last-Modified: Tue, 17 Jan 2023 13:53:07 GMT, Vary: Accept-Encoding, CF-Cache-Status: DYNAMIC, Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=GZ7HZLwXVyB%2BXRzpcYY4A%2BjpGd0h0S8EsbSRWwMm0b8UbQrnqWpmB8e%2FFEYkNsZUVUdCWboRsWP%2B0aC6YJETfHGZU%2FU%2BFyhetR6%2FA8527KxVKfuGTjpr0Chp"}],"group":"cf-nel","max_age":604800}, NEL: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}, Server: cloudflare, CF-RAY: 7953d5d82a3c384d-MAD, alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400),HttpEntity.Chunked(text/html),HttpProtocol(HTTP/1.1))
英文:

This code:

trait HttpServer {
def sendAndReceive: HttpRequest => Future[HttpResponse]
}
trait ApiHandler extends HttpServer {
implicit def as: ActorSystem
override def sendAndReceive: HttpRequest => Future[HttpResponse] =
Http().singleRequest(_)
}
trait Api {
this: ApiHandler =>
implicit def as: ActorSystem
implicit def mat: Materializer
implicit def ec: ExecutionContext
def request(httpRequest: HttpRequest) = {
sendAndReceive(httpRequest).flatMap {
response =>
response.status match {
case StatusCodes.OK => Future.successful(response)
case _ => throw new RuntimeException("error")
}
}
}
}
class ApiImpl()(implicit val as: ActorSystem, val mat: Materializer, val ec: ExecutionContext) extends Api with ApiHandler {
def request2 = {
val httpRequest = Get("https://akka.io")
request(httpRequest)
}
}
def main(args: Array[String]): Unit = {
implicit val actorSystem = ActorSystem("system")
implicit val executionContext = actorSystem.dispatcher
implicit val materializer = ActorMaterializer()
val api = new ApiImpl()
api.request2.map(println(_))
}

with versions:

val akkaVersion = "2.6.7"
val akkaHttpVersion = "10.1.12"

Works properly:

HttpResponse(200 OK,List(Date: Mon, 06 Feb 2023 12:19:39 GMT, Connection: keep-alive, Last-Modified: Tue, 17 Jan 2023 13:53:07 GMT, Vary: Accept-Encoding, CF-Cache-Status: DYNAMIC, Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=GZ7HZLwXVyB%2BXRzpcYY4A%2BjpGd0h0S8EsbSRWwMm0b8UbQrnqWpmB8e%2FFEYkNsZUVUdCWboRsWP%2B0aC6YJETfHGZU%2FU%2BFyhetR6%2FA8527KxVKfuGTjpr0Chp"}],"group":"cf-nel","max_age":604800}, NEL: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}, Server: cloudflare, CF-RAY: 7953d5d82a3c384d-MAD, alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400),HttpEntity.Chunked(text/html),HttpProtocol(HTTP/1.1))

huangapple
  • 本文由 发表于 2023年2月6日 18:34:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75360145.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定