Пересылка (загрузка / выгрузка) большого файла через Akka HTTP / Akka Streams - PullRequest
3 голосов
/ 06 февраля 2020

У меня есть служба, которая берет запрос HttpRequest от клиента, чтобы получить файл с другого сервера через REST, а затем перенаправляет файл клиенту как HttpResponse.

Не спрашивайте меня, почему клиент не сам не запрашиваю файл, потому что это длинная история.

Я скомпилировал стратегию, чтобы загрузить файл в файловую систему и затем отправить файл клиенту. Для этого используются выдержки из других ответов stackoveflow от @ RamonJRomeroyVigil.

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 Ответ

2 голосов
/ 06 февраля 2020

Поскольку вы уже получаете файл в виде потока со второго сервера, вы можете переслать его непосредственно клиенту. Вам нужно только построить свой 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-connections и akka.http.client.host-connection-pool.max-open-requests. Более подробную информацию можно найти здесь .

...