scala - Akka http 请求在通过管道传输给 actor 时不会被 runFold 使用

标签 scala akka akka-http

我的代码基于 Akka 文档中的示例,因此它应该可以正常工作,但问题是我只收到响应的 header 、内容长度,当涉及到折叠主体时,我得到:

[INFO] [08/17/2016 13:01:21.116] [default-akka.actor.default-dispatcher-9] [akka://default/user/$a] Length: 29407

[INFO] [08/17/2016 13:01:21.127] [default-akka.actor.default-dispatcher-9] [akka://default/user/$a] Got response, body: List()

Actor 代码:

class AkkaHttp extends Actor with ActorLogging {

  import akka.pattern.pipe
  import context.dispatcher

  final implicit val materializer: ActorMaterializer = ActorMaterializer(ActorMaterializerSettings(context.system))

  val http = Http(context.system)

  override def preStart() = {
    http.singleRequest(HttpRequest(uri = "http://akka.io/"))
      .pipeTo(self)
  }

  def receive = {
    case s: String => {
      log.info(s)
    }
    case HttpResponse(StatusCodes.OK, headers, entity, _) => {
      log.info("Length: " + entity.contentLengthOption.getOrElse("No content"))
      log.info("Got response, body: " + entity.dataBytes.runFold(ByteString.empty) {
        case (acc, b) => acc ++ b }.map(s => s.utf8String))
    }
    case HttpResponse(code, _, _, _) =>
      log.info("Request failed, response code: " + code)
  }

}

如果我更改 preStart() 方法以在其中折叠响应并仅发送字符串,则会记录页面正文:

  override def preStart() = {
    val httpRequest: HttpRequest = HttpRequest(uri = "http://akka.io/")
    val request = http.singleRequest(httpRequest)
    request.flatMap { response =>
      response.entity.dataBytes.runFold(ByteString.empty) { 
          case (acc, b) => acc ++ b }.map(f => f.utf8String)
    }
    .pipeTo(self)
  }

响应实体在第一个版本中没有折叠的原因可能是什么?

最佳答案

runFold 的结果是另一个 Future。然后你去尝试打印那个 Future,它不会产生任何有值(value)的东西,因为它是一个 Future 而不是底层的 String想。如果您将 receive 中的大小写更改为此,那么它应该开始工作:

case HttpResponse(StatusCodes.OK, headers, entity, _) => 
  log.info("Length: " + entity.contentLengthOption.getOrElse("No content"))

  val entityFut = 
    entity.dataBytes.runFold(ByteString.empty) {
      case (acc, b) => acc ++ b 
    }.
    map(s => s.utf8String)
  entityFut pipeTo self

关于scala - Akka http 请求在通过管道传输给 actor 时不会被 runFold 使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38995224/

相关文章:

scala - Azure Databricks Notebook 在包中时无法找到 "dbutils"

unit-testing - Scala 的代码覆盖率工具

java - Akka 从源代码修改/创建配置文件

scala - 如何在运行时为 docker 容器提供端口号?

java - 在 Akka HTTP 中保持 WebSocket 连接处于 Activity 状态的最佳方法?

scala - Option、Either 等上的折叠和 Traversable 上的折叠有什么关系?

scala - 在 Scala 中实例化赋值运算符两侧的对象;它是如何工作的

java - 如何将 IndirectActorProducer 与具有辅助参数的工厂一起使用?

scala - Play 框架 2.0 Controller /异步究竟是如何工作的?

scala - 如何在 Akka Http 中发送响应代码作为响应?