通过Akka HTTP / Akka流转发(下载/上传)大文件

时间:2020-02-05 21:54:43

标签: scala akka-stream akka-http

我有一项服务,该服务从客户端获取HttpRequest以通过REST从另一台服务器获取文件,然后将文件作为HttpResponse转发给客户端。

别问我为什么客户不索要他/她自己的文件,因为这是一个漫长的故事。

我制定了一种策略,将文件下载到文件系统,然后将文件发送给客户端。这是从@RamonJRomeroyVigil的其他stackoveflow响应中提取的。

def downloadFile(request: HttpRequest, fileName: String): Future[IOResult] = {
  Http().singleRequest(request).flatMap { response =>
    val source = response.entity.dataBytes
    source.runWith(FileIO.toPath(filePath))
  }
}

def buildResponse(fileName: String)
  val bufferedSrc = scala.io.Source.fromFile(fileName)
  val source = Source
    .fromIterator(() => bufferedSrc.getLines())
    .map(ChunkStreamPart.apply)

  HttpResponse(entity = HttpEntity.Chunked(ContentTypes.`application/octet-stream`, source))
}

但是,我想一步一步地完成此操作,而不保存文件系统并利用流式传输功能。

我还想将客户端可以同时处理的请求数量限制为5。

谢谢

1 个答案:

答案 0 :(得分:2)

由于您已经从第二台服务器获取文件作为流,因此可以将其直接转发到客户端。您只需要即时构建HttpResponse即可:

def downloadFile(request: HttpRequest) : Future[HttpResponse] = {
    Http().singleRequest(request).map {
      case okResponse @ HttpResponse(StatusCodes.OK, _, _, _) =>
        HttpResponse(
          entity = HttpEntity.Chunked(ContentTypes.`application/octet-stream`,
            okResponse
              .entity
              .dataBytes
              .map(ChunkStreamPart.apply)
          ))

      case nokResponse @ HttpResponse(_, _, _, _) =>
        nokResponse
    }
  }

要更改客户端允许的最大并发请求数,您需要设置akka.http.client.host-connection-pool.max-connectionsakka.http.client.host-connection-pool.max-open-requests。可以在AmazonS3ClientBuilder#standard中找到更多详细信息。