Delphi. Делаем мультизагрузку файлов чанками по HTTP протоколу (с idHTTP на idHTTPServer)

Загрузку чанками одного файла с idHTTP на idHTTPServer я уже организовал ранее, в данной статье посмотрим как можно организовать мультизагрузку (в данном случае последовательную). Пользователь выбирает N файлов и файлы поочередно начинают грузиться на сервер чанками.

10

9

В данном примере реализована последовательная загрузка файлов через единый компонент idHTTP. Пример нетривиальный, и я не вижу возможности описать все в одном посте, поэтому просто выложу исходники и дам некоторые комментарии. В принципе, можно переписать код на параллельную загрузку, размножив idHTTP, но я предпочел оставить так, чтобы не перегружать сервер, чтобы в один момент времени при загрузке, с ним работал один поток от одного клиента. А то, если сделать мультизагрузку с одновременным открытием потоков на сервере, и каждый клиент захочет загружать по 150 файлов, то что из этого выйдет? Явно возможна перегрузка сервера по памяти. Хотя там и можно выставить ограничение на самом сервере, но тогда будут ошибки на клиенте, в общем, на мой взгляд – последовательно загружать лучше! Код выполняет минимальный функционал и является примером, думаю, все ограничения можно легко добавить, разобравшись в нём. В текущих исходниках код отправляем файлы чанками по 4 мб или целиком если меньше этого размера. Ограничение на максимальный размер файла не установлено, логи операций ведутся на клиенте.

Исходники

Скачать исходники

Делал в Delphi Seattle

Проектная группа состоит из 3 частей

Сервер – простое VCL приложение с компонентом idHTTPServer

Клиент – компонент, созданный на основе TPanel, с idHTTP на борту

Ну и тестовая программа, на которую погружается разрабатываемый компонент

85

Компонент нужно установить – прописать все пути. У меня при прописывании путей не всегда подхватываются библиотеки, прописанные в Tools>Options>DelphiOptions>Library, некоторые пути пришлось прописать в Project > Options > SearchPath, в частности, для TestHTTPClient.exe получилось так…

11

То есть, я прямо указал, где лежат модули для разрабатываемого компонента, иначе он не желал их искать, хотя ровно тоже самое было написано в Tools>Options>DelphiOptions>Library. После успешной установки и запуска клиента и сервера. После установки всего и запуска клиента и сервера, нужно нажать на кнопку bTest, чтобы открылось диалоговое окно загрузки файлов. Пока что функционал “мультизагрузки” прицеплен к этой кнопке.

13

Описание некоторых моментов

Загрузка одного файла чанками c idHTTP на клиенте на idHTTPServer описана в одном из предыдущих постов.

Но после публикации того поста обнаружил некоторые мелкие “недоделки”, в частности, проблемы с отправкой файлов с русскими именами, но это вопрос я решил в соответствующем посте.

В тех исходниках, которые я выложил выше эта проблема исправлена, ну и ряд других.

Основная идея

Вот основные модули, ответственные за отправку файлов чанками многопоточно

12

В модуле uSendFileInChunks.pas код ответственный за отправку одного файла чанками. В модуле uSendFileInChunksThread.pas создается поток, который вызывает экземпляр класса из uSendFileInChunks, а в модуле uSendManyFilesInChunks – создание Object Lists для потоков отправки отдельных файлов и фрэймов визуализации и отправка файлов на сервер в цикле.

Некоторое время повозился с синхронизацией, так как не все было очевидно с первого взгляда. В частности, я понял, что при использовании нескольких объектов синхронизации одновременно происходят так называемые дедлоки и мы получаем “облом”, поэтому важно использовать в один момент времени один объект синхронизации участка кода.

Итак, посмотрим на некоторые участки кода. Центральный модуль для этой задачи, это uSendManyFilesInChunks.

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

Модуль uSendFileInChunksThread выглядит следующим образом.

Тут есть ещё немного закомментированного мусора, поэтому его можно просто удалить. Так, как написано сейчас – вполне работает.

Ну и последний модуль – отправки одного файла, код которого вызывается в потоке.

Описание серверной части я оставлю. В принципе, в ней нет ничего суперсложного. Для меня в данном коде самым сложным было правильно синхронизировать объекты, используемые в потоках.

Тестируем

Запускаем сервер

14

Запускаем клиент

13

Жмем на кнопку bTest и выбираем файлы для загрузки

10

После этого смотрим на работу клиента и сервера

9

Успехов Вам в программировании !!! Если будут вопросы – пишите.

This entry was posted in Delphi, Потоки(Threads). Bookmark the permalink.

Leave a Reply