Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.03.2009, 14:21   #1
milkfake
 
Регистрация: 04.03.2009
Сообщений: 4
По умолчанию Indy и поток

Задача:
1. Залогиниться на сайт
2. Сделать несколько запропросов одновременно/паралельно
3. Обработать их результат.

Использую Indy10. После первого коннекта, который отправляет на сайт логин и пароль для клиента создается сессия на сервере. Пока его не отдисконнектить, я могу спокойненько делать любые GET/Post запросы последовательно, используя 1 копию компонента.

Внимание вопрос! Как делать, скажем, 5 запросов паралельно используя созданную сессию?
milkfake вне форума Ответить с цитированием
Старый 04.03.2009, 15:05   #2
knight
Дон Кихот
Форумчанин
 
Аватар для knight
 
Регистрация: 17.01.2008
Сообщений: 130
По умолчанию

1. Описываешь поток с запросом
2. Запускаешь N потоков
Если нет проверки на сайте по IP, то сработает, иначе звиснет на первом потоке

Пример потока
Код:
//****************************************************************************//
//класс единичного потока для определения задержки HTTP запроса
//****************************************************************************//
unit MyThread;

interface

//подключение стандартных библиотек Delphi
uses
  Classes, ExtCtrls, IdHTTP, SysUtils, Windows;

type

  //Поток HTTP запроса
  TMyThread = class(TThread)
  private
    FURL: string;                    //HTTP адрес
    FDuration: Cardinal;             //задержка в мс
  protected
    procedure Query;                 //HTTP запрос
  public
    constructor Create(AURL: string);//создание потока
    procedure Execute; override;     //действия потока

  published
    property Duration: Cardinal read FDuration; //доступ к значению задержки
    property URL: string read FURL;             //доступ к значению HTTP адреса
  end;


implementation

//создание потока
constructor TMyThread.Create(AURL: string);
begin
  FURL := AURL;             //запоминаем HTTP адрес
  inherited Create( False); //создаем поток и сразу его запускаем
end;

//HTTP запрос
procedure TMyThread.Query;
var
  HTTP: TIdHTTP;            //компонент Indy для работы с HTTTP
  Duration: Double;         //переменная для вычисления задержки
begin

   HTTP:=TIdHTTP.Create(nil);   //создаем объект TIdHTTP
   HTTP.HandleRedirects:=True;  //включили возможность redirect на другие HTTP адреса
   HTTP.ProtocolVersion:=pv1_0; //наиболее распространенная версия HTTP протокола
   HTTP.ReadTimeout := 1000;    //если время больше секунды, считаем, что ответа нет


 try
    Duration:= Now;             //выставим текущее время
    HTTP.Get(FURL);             //запустим GET запрос

    Duration:= Now - Duration;         //вычислим задержку
    Duration:= Duration*24*60*60*1000; //переведем ее в мс
    FDuration := round(Duration);      //вернем задержку во внутреннюю переменную

 except
    FDuration := round(Duration);      //вернем задержку во внутреннюю переменную
    HTTP.Free;                         //освободим память от отъекта TIdHTTP
    Terminate;                         //прервем работу потока
 end;

 FDuration := round(Duration);         //вернем задержку во внутреннюю переменную
 HTTP.Disconnect;                      //отключим корректно TIdHTTP
 HTTP.Free;                            //освободим память от отъекта TIdHTTP
 Terminate;                            //прервем работу потока
end;


//действия потока
procedure TMyThread.Execute;
begin
  Query; //HTTP запрос
end;

begin
end.

Последний раз редактировалось KORN; 05.03.2009 в 08:44. Причина: пользуйемся правкой
knight вне форума Ответить с цитированием
Старый 04.03.2009, 15:33   #3
milkfake
 
Регистрация: 04.03.2009
Сообщений: 4
По умолчанию

Хочется уточнить один момент. Вы предлагает создовать несколько экземпляров idHTTP в потоках, что вполне логично, однако для того, чтобы поддерживать сессию необходимо кроме одного IP использовать cookie, которые были получены при первом коннекте, иначе придется логиниться постоянно, а это было бы нежелательно.
milkfake вне форума Ответить с цитированием
Старый 04.03.2009, 18:31   #4
knight
Дон Кихот
Форумчанин
 
Аватар для knight
 
Регистрация: 17.01.2008
Сообщений: 130
По умолчанию

cookie можно сделать общий для всех потоков... я вроде где-то так уже делал....
knight вне форума Ответить с цитированием
Старый 04.03.2009, 23:27   #5
milkfake
 
Регистрация: 04.03.2009
Сообщений: 4
По умолчанию

А еще вопрос как запустить число потоков "на выбор"? Т.е. я в Edit указываю цифирку сколько потоков использовать, а программа их создает.
milkfake вне форума Ответить с цитированием
Старый 04.03.2009, 23:28   #6
Квэнди
Старожил
 
Аватар для Квэнди
 
Регистрация: 13.12.2006
Сообщений: 3,859
По умолчанию

динамический массив потоков
ICQ не для вопросов, а для предложений. Для вопросов используйте форум
IRC канал клуба программистов|Мои статьи
Квэнди вне форума Ответить с цитированием
Старый 05.03.2009, 08:35   #7
knight
Дон Кихот
Форумчанин
 
Аватар для knight
 
Регистрация: 17.01.2008
Сообщений: 130
По умолчанию

Как сказала бы Масяня: "Как-то так"
Код:
var
  MyThread: array of TMyThread;                        //массив потоков

         j:= 0;
         jthreads := StrToInt(Edit1.Text)-1;
         while j <= jthreads do
           begin

            SetLength(MyThread, ThreadsAll + 1);

            MyThread[ThreadsAll] := TMyThread.Create(Memo2.Lines.Strings[i]); //формирование потока
            MyThread[ThreadsAll].OnTerminate := ThreadDone;                   //установка процедуры завершения
            Inc(ThreadsAll);                                                  //прибавим счетчик потоков

            Inc(ThreadsRunning);                                     //прибавим счетчик запущенных потоков
            Inc(j);
           end;
ThreadsAll - кол-во потоков (integer)
ThreadsRunning - кол-во запущенных потоков (integer)

Последний раз редактировалось KORN; 05.03.2009 в 08:42. Причина: пользуйемся правкой
knight вне форума Ответить с цитированием
Старый 05.03.2009, 08:42   #8
Квэнди
Старожил
 
Аватар для Квэнди
 
Регистрация: 13.12.2006
Сообщений: 3,859
По умолчанию

Только в случае использования Indy 10 (начиная с какой именно версии не помню) все это реализуется еще проще:
вкладка IndyMisc
компоненты
TidThreaadComponent
TIdSchedulerOfThreadPool
ICQ не для вопросов, а для предложений. Для вопросов используйте форум
IRC канал клуба программистов|Мои статьи
Квэнди вне форума Ответить с цитированием
Старый 06.03.2009, 10:14   #9
milkfake
 
Регистрация: 04.03.2009
Сообщений: 4
По умолчанию

knight, Квэнди, большое вам спасибо! Все работает!

Вот еще вопрос. Есть у меня набор процедур в главном модуле, которые работают с dll. Схема такая:

Unit1 -запускает поток-> который должен используя функции DLL выполнить задачу.

Как это лучше сделать? Синхронизировать импорт DLL? Можно ли использовать фукции DLL используя статичную загрузку? Например я в начале работы программы ее подгрузил, а в потоке только методы использовать?

Последний раз редактировалось milkfake; 06.03.2009 в 10:18.
milkfake вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как обновить indy 9 на indy 10 Пилигрим Компоненты Delphi 16 30.04.2010 10:11
Indy 9 против Indy 10 OrdJONY Свободное общение 2 08.11.2008 20:28
Поток Черничный Общие вопросы Delphi 5 27.09.2008 21:23
Поток в никуда... prizrak1390 Работа с сетью в Delphi 1 30.06.2008 10:32
поток файлов мандарин Общие вопросы Delphi 1 24.04.2007 12:20