Вы здесь

Synapse. Скачиваем данные с ProgressBar’ом

Если Вы используете в работе с Сетью библиотеку Synapse, то, вероятно задумывались о том как сделать так, чтобы не просто получать или отправлять данные, но и видеть весь ход процесса. Например, чтобы при скачивании данных заполнялся ProgressBar, или чтобы в процессе работы THTTPSend видеть весь лог его работы, начиная от создания и, заканчивая закрытием сокета.
Сделать это достаточно просто, подключив в uses всего один модуль – blcksock.

У объекта THTTPSend имеются следующие свойства:

 

Которые, судя по описанию, в каждый момент времени содержат размер полученных и отправленных данных в байтах. И для того, чтобы получать эти значения достаточно определить событие OnStatus у сокета. На самом деле эти свойства содержат либо 0 и это значит, что данные ещё не принимаются и не отправляются, либо уже принятый или отправленный размер данных.
Убедиться в этом можно следующим образом. Создадим новое приложение и подключим в Uses модули httpsend и blcksock. На форму положим Memo в который будем выводить значения DownloadSize.
Создадим глобальную переменную HTTP: THTTPSend и напишем обработчик события OnStatus у сокета:

 

А на OnCreate главной формы:

 

Теперь запустим программу и посмотрим, что выпишется в Memo. У меня получились следующие строки:

 

То есть – прогресса толком и нет. Либо 0, либо сразу всё. Поэтому использование этих свойств оставим на потом. А лучше воспользуемся теми данными, которые возвращает нам сокет, т.е.

 

Reason – это тип события
Value - значение, возвращаемое при определенном событии.
Всего на OnStatus можно получить данные по четырнадцати различным событиям, но для нас сейчас особую роль будут играть два из них: HR_ReadCount и HR_WriteCount. При первом событии в Value вернется строка, содержащая количество прочитанных байтов, при втором – отправленных.
Соответственно, можно завести какую-нибудь переменную типа integer и каждый раз при событии HR_ReadCount или HR_WriteCount прибавлять к этой переменной значение StrToInt(Value) и заполнять ProgressBar.
Осталось только определить максимальное значение у ProgressBar’a (кстати, можете его уже уложить на форму). Сделать это достаточно просто, отправив запрос “HEAD” на нужный адрес и проанализировав заголовок “Content-Length”. Можно воспользоваться, к примеру, такой функцией:

 

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

 

Ну, а теперь нам осталось только немного подправить процедуру Status. Создайте ещё одну переменную, например:

 

В ней будем хранить общее количество полученных данных. Будем в Memo выписывать весь лог и заполнять ProgressBar, поэтому подключите дополнительно в uses TypInfo и дописываем Status:

 

Теперь вешаем на форму кнопку и в обработчике onClick пишем:

 

Здесь следует заметить, что после того как данные получены и переданы дальше на обработку обязательно необходимо выполнять Clear у THTTPSend, иначе при следующем GET-запросе объект попробует не только получить данные, но и отправить все, что было получено при предыдущем запросе, включая куки и заголовки, что приведет к ошибке.
Вот теперь можете запускать программу и смотреть как заполняется ProgressBar при скачивании файла, а в Memo выводится лог работы объекта THTTPSend.
Также, для получения каких либо данных от сокета вы можете определить событие OnHeartBeat (“Сердцебиение”), которое будет срабатывать в заданные промежутки времени, но, как говорят сами разработчики Synaps’а – слишком частое использование этого события может привести к “подвисанию” приложения, поэтому лучше сильно не рисковать.

Скачать пример можно с сайта автора статьи.