Delphi. Отправка файла чанками по HTTP протоколу. Компоненты TPS_ChunkUploader и TPS_HTTPFileServerAddon

Решил оформить предыдущие труды по отправке файла на HTTP сервер чанками в виде компонент ( и клиентская и серверная части созданы от TComponent) и немного упорядочить код и сделать его более прозрачным и понятным. Не знаю, насколько это у меня получилось, но попробовал. Также добавил юнит-тестов. Даже пробовал делать все в стиле TDD, но не крут я пока для этого подхода. Что же, будем учиться.

Зачем отправлять файл чанками?

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

Вообще тут что то вроде баланса между скоростью и устойчивостью. Можно отправлять файл целиком, но устойчивость тут никакая, а можно отправлять очень маленькими кусочками, но тогда скорость никакая. Это тема отдельных тестов.

В данной версии компонент нет функции отправки файла с места обрыва, я только начал ее писать, пока не хватило моральных сил, так как нет супер необходимости для того проекта, который я делаю. Но сделать эту функцию не так сложно, как я вижу. По своим силам вечер-два.

Текущая версия просто делит файл на чанки заданного размера, отправляет их один за одним на сервер. Я всё же придерживаюсь последовательной передачи, потому как если лить в несколько потоков, да ещё несколько юзеров – может случиться out of memory или другого ресурса.

К текущему моменту я понял как важна атомарность в программировании, чтобы каждый отдельный компонент, модуль делал только одну свою маленькую функцию. Раньше лепил все подряд и код получался кашевидным) Поэтому в TPS_ChunkUploader только отправка на сервер. И несколько основных событий, то есть вот так…

6

Лучше всего тестировать в отдельном потоке – все преимущества многопоточного программирования так сказать – ничего не висит, файл, даже если большой – просто передается. А первые 2 кнопки отправляют файл в основном потоке.

Справа как вы видите обработка событий, не всех, но об этом позже.

Основная идея алгоритма

Если файл меньше размера чанка – отправить его полностью, если больше – делить на чанки, собрать их в отдельной директории на диске, собрать по ним статистику в  файл в JSON формате – отправить этот файл в той же временной папке , отправлять по кусочками сами чанки, запросить сервер – все ли кусочки дошли, собрать файл и в любом случае – уничтожить временные директории на клиенте и сервере

На сервере все загружается в “папку текущего дня”, примерно так public/files/1/2017/2/9, 1 в данном случае означает ID пользователя. То есть под каждого пользователя своя папка на сервере.

Как настроить и использовать компонент TPS_ChunkUploader?

Я делаю это как-то вот так… После прописывания всех необходимых путей, инсталляции bpl, бросаем компонент на форму

7

Настраиваем его таким образом, прописываем HTTP параметры, ReatTimeOut и события, более подробно смотрите в исходниках

Я здесь разберу пример использования только через отправку в отдельном потоке, выглядит это таким образом

Собственно ничего сложного нет. Вся основная кухня в модуле потока. Смотрите исходники.

Почему серверная часть в виде какого-то аддона?

Можно было сделать ее как отдельный независимый компонент, но мне надо было какой-то промежуточный компонент, нечто вроде добавки к серверу, так как сам сервер у меня уже есть. Это UniGUI сервер, собственно.

Как настроить и использовать компонент TPS_HTTPFileServerAddon ?

По аналогии – бросаем его на форму

8

Настраиваем его примерно таким образом

Остальное смотрите в исходниках.

Джентельменский набор запросов сервера для данной задачи я сформулировал таким образом

Как видите, этот Addon я использую, чтобы обработать запросы сервера. В дальнейшем много-много всего можно будет усовершенствовать, но пока что так.

Юнит-Тесты

К клиентской части написал 16 юнит тестов по всем основным функциям. Поскольку это клиент-серверная технология, то прохождение тестов на клиенте косвенно говорит о нормальной функциональности на сервере, для сервера отдельные тесты писать не стал.

9

Над тестами еще надо поработать – кое какие из них оставляют лишние файлы и папки на клиенте, но это потом.

События

Я создал следующие события

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

Иcходники

05_ChunkUploader

08_HTTPFileServerAddon

 

 

This entry was posted in Delphi, Компонентостроение, Мои компоненты. Bookmark the permalink.