2015-01-26 1 views
4

Я знаю, что очень похожие вопросы были заданы раньше. Но я не думаю, что решения, которые я нашел в google/stackoverflow, подходят мне.Отправка больших файлов с помощью Spray

Я начал писать некоторые веб-сервисы с помощью Scala/Spray, и кажется, что лучший способ отправить большие файлы, не потребляя больших ресурсов памяти, - это использование сортировки потоков. Таким образом, Spray отправит http-фрагменты. Два вопроса:

  1. Можно ли отправить файл без использования фрагментов HTTP и без чтения всего файла в память?

  2. AFAIK akka.io обрабатывает только одну запись за раз, что означает, что она может буферизировать одну запись до тех пор, пока она не будет полностью передана ядру O/S. Можно ли сообщить Spray для каждого ответа HTTP длину содержимого? После этого Spray будет запрашивать новые данные (через сообщения akka) до завершения всей длины содержимого. Например, я указываю, что длина моего контента составляет 100 байт. Spray отправляет сообщение, запрашивающее данные для моего актера, я предоставляю 50 байтов. Когда эти данные передаются на O/S, спрей отправляет другое сообщение с запросом новых данных. Я предоставляю оставшиеся 50 байтов ... ответ завершен.

ответ

2

Можно ли отправить файл без использования HTTP ломти [на проводе]

Да, нужно, чтобы включить chunkless потокового видео. См. http://spray.io/documentation/1.2.4/spray-routing/advanced-topics/response-streaming/

Бескабельная потоковая передача работает независимо от того, используете ли вы маршаллер Stream или предоставляете ответ как MessageChunk. См. Приведенный ниже пример.

, не читая весь файл в память

Да, это должно работать, если вы предоставляете данные как Stream[Array[Byte]] или Stream[ByteString].

[...] После этого спрей будет просить новые данные [...]

Это на самом деле почти как он уже работает: Если вы вручную обеспечить ломти вы можете запросить пользовательское Ack сообщение который будет доставлен обратно вам, когда слой спрея может обрабатывать следующую деталь. См. this example о том, как вытекать из маршрута распыления.

Я указываю мой длина содержание 100 байт

Примечание авансовые: В HTTP не строго необходимо указать Content-Length для ответов, потому что тело ответа может быть ограничена закрытием соединение - это то, что спрей делает, если разрешено потоковое воспроизведение. Однако, если вы не хотите закрывать соединение (потому что вы потеряете это постоянное соединение), вы можете теперь указать явный заголовок Content-Length в своем сообщении ChunkedResponseStart (см. #802), что предотвратит закрытие соединения.

+0

Спасибо! Отличный ответ! – sapito