Как непрерывно передавать файл с помощью boost :: beast - PullRequest
1 голос
/ 30 марта 2020

У меня есть локальный файл, к которому постоянно добавляется какой-то процесс. Я хотел бы предоставить этот файл с boost::beast.

. До сих пор я использую boost::beast::http::response<boost::beast::http::file_body> и boost::beast::http::async_write для отправки файла клиенту. Это работает очень хорошо, и хорошо, что boost::beast позаботится обо всем. Однако, когда достигается конец файла, он останавливает асинхронную запись. Я предполагаю, что это потому, что is_done базового serializer возвращает true в этот момент.

Возможно ли поддерживать асинхронную запись в непрерывном режиме, чтобы новое содержимое записывалось клиенту по мере роста локального файла (аналогично тому, как tail -f будет продолжать записывать содержимое файла в стандартный вывод)?

Я подумал, что мне может понадобиться использовать boost::beast::http::response_serializer<boost::beast::http::file_body> для такой настройки, но я не уверен, как использовать это правильно. И нужно ли для этой цели использовать chunked-кодировку?

Обратите внимание, что поддержание открытого HTTP-соединения не является проблемой, а только дальнейшая запись результатов по мере роста файла.

1 Ответ

1 голос
/ 31 марта 2020

После некоторых исследований эта проблема, кажется, не легко решаема, по крайней мере, не в GNU / Linux, на котором я сейчас сосредоточен.

Возможно использовать кодирование по частям, как описано в boost::beast ' документация Я реализовал обслуживание фрагментов асинхронно из содержимого файлов, которые также читаются асинхронно с помощью boost::asio::posix::stream_descriptor. Это работает довольно хорошо. Тем не менее, он также останавливается с ошибкой конца файла, как только достигается конец файла. При использовании async_wait через дескриптор я получаю сообщение об ошибке «Операция не поддерживается».

Таким образом, просто кажется невозможным асинхронное ожидание записи большего количества байтов в файл. Это странно, учитывая, что tail -f делает именно это. Итак, я strace ed tail -f, и получается, что он вызывает inotify_add_watch(4, "path_to_file", IN_MODIFY). Следовательно, я полагаю, что для реализации этого на самом деле нужно использовать inotify.

Мне кажется, что проще и эффективнее взять под контроль процесс, который записывает в файл до сих пор, чтобы позволить ему печатать в стандартный вывод. Затем я могу транслировать канал (аналогично тому, как я пытался транслировать файл) и сам записать файл.

Однако, если кто-то хочет go в будущем, я полагаю, что с помощью inotify и boost::asio::posix::stream_descriptor является ответом на вопрос, по крайней мере, в GNU / Linux.

...