Правильно сменить прокси при многопоточной работе с Indy

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Diamantx, 29 May 2013.

  1. Diamantx

    Diamantx New Member

    Joined:
    17 Feb 2012
    Messages:
    64
    Likes Received:
    1
    Reputations:
    0
    Значит работаю с определенным сайтом, общаюсь с ними через idHTTP. В какой-то момент сайт блокирует IP и при ошибке нужно выполнить определенное действие, после чего сменить прокси. Как оформить код правильно, чтобы смена IP не произошла дважды?
     
  2. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Когда ip заблокировали - задаешь новый прокси. Вроде несложный алгоритм.
     
  3. Eich3

    Eich3 Member

    Joined:
    27 Jan 2013
    Messages:
    22
    Likes Received:
    7
    Reputations:
    5
    Можно объявить и использовать свой класс, хранящий приватно TidHTTP, предоставляющий необходимые для задачи методы (Get/Post) и свойства (Request, Response).

    В перехваченных функциях Get и Post делаем вызов к компоненту, проверяя результат. В случае ошибки, меняем адрес и пробуем снова.
     
  4. Diamantx

    Diamantx New Member

    Joined:
    17 Feb 2012
    Messages:
    64
    Likes Received:
    1
    Reputations:
    0
    Тут смысл в том, что, например, первый поток получил ошибку о бане ip и меняет прокси, а второй поток уже эту проксю тоже убил и первому снова прийдется менять ip. А если таких потоков с десяток. Как выкидывать уже убитые прокси на какое-то время?
     
  5. Eich3

    Eich3 Member

    Joined:
    27 Jan 2013
    Messages:
    22
    Likes Received:
    7
    Reputations:
    5
    А если "сдохнет" прокси? Нужен отдельный класс, который разруливает все ситуации, связанные с доступом к ресурсу. При желании, можно сделать методы Get и Post синхронизированными, а объект - разделяемым. Тогда в случае неудачи адрес сменит гарантированно только один поток.

    Code:
    type
    TMyHTTPClient = class(TObject)
    private
     FHttpClient : TIdHTTP;
     procedure ChangeProxy;
    
    public
     constructor Create;
     destructor Destroy; 
     function Get(URL : string) : string;
     // пробросить другие методы/свойства, если нужно
    
    end;
    
    
    Пример реализации метода Get:
    Code:
    function TMyHTTPClient.Get(URL : string) : string;
    var
        text : string;
    begin
      try
        text := FHttpClient.Get(URL)
        // здесь еще можно проверить содержимое ответа,
        // на наличие признаков бана
        Result := text; // если все ОК    
      except
      on E : EIdException do
      begin
       // здесь обрабатываем ошибку, при необходимости
       // вызываем внутреннюю процедуру ChangeProxy   
      end;
      end;
      // повторяем запрос, если нужно. Можно сделать циклом
      // с настраиваемым количеством попыток
    end;
    
     
    #5 Eich3, 29 May 2013
    Last edited: 29 May 2013