Akka http 请求在通过管道传输到 actor 时不会与 runFold 一起使用



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

[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] get response, body: List()

演员代码:

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,它不会产生任何有价值的东西,因为它是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

最新更新