13

I have built a simple website monitoring application using Indy TIdhttp component. I want to detect when a designated page is not returned within a specified time frame (I am using 5000 milliseconds). As a test I created a page on a web site which intentionally takes 15 seconds to respond. But I can't get my procedure to "give up" after the 5 seconds. I have tried ReadTimeout, a suggested solution using a timer and the OnWorkBegin event (was never able to get OnWorkBegin to fire immediately after the get call).

Note I am not worried about a connection timeout. My concern here is a timeout for the server to return with a page.

Here is some source code I have been using. It contains many of the elements I reference.

procedure TServLogic.WorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64);
begin
  GetTimer.Enabled := True;
end;
procedure TServLogic.WorkEnd(ASender: TObject; AWorkMode: TWorkMode);
begin
  GetTimer.Enabled := False;
end;

procedure TServLogic.GetTimerTimer(Sender: TObject);
begin
  idHttp.Disconnect(True);
end;

procedure TServLogic.CallHttp(mlink: String): String;
begin
  result := '';
  GetTimer := TTimer.create(nil);
  GetTimer.OnTimer := GetTimerTimer;
  GetTimer.Interval := 5000;
  try
    IdHTTP := TIdHTTP.create(nil);
    idhttp.ReadTimeout := 5000;
    IdHttp.OnWorkBegin := WorkBegin;
    IdHttp.OnWorkEnd   := WorkEnd;
    try
      result  := idhttp.get(mLink);
    except
      on e:exception do begin
        AppendToLog('Server did not respond withing 5 seconds');
      end;
    end;
  finally
    GetTimer.Free;
    idhttp.free;
  end;
end;
Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
M Schenkel
  • 6,294
  • 12
  • 62
  • 107
  • See also: [The connection does not time out while using Indy](http://stackoverflow.com/questions/3187446/the-connection-does-not-timeout-while-using-indy). – Rob Kennedy Jul 23 '10 at 04:41
  • 2
    Your logic with TTimer expects asynchronous TIdHTTP which is not true – Free Consulting Jul 23 '10 at 07:54
  • Looked over the article suggested by Rob Kennedy. I have created a threaded type solution. Created a TStringList in the main application to manage my threads. I also have a timer which fires every 5 seconds. So if I see a thread that has not "finished" in 5 seconds I call the Terminate method of the thread. But this does not seem to "Terminate" it immediately they way I want to; it still seems to wait. – M Schenkel Jul 23 '10 at 16:10
  • 5
    Asking the thread to terminate itself won't really work since Indy threads are blocking. They won't check whether they've been asked to terminate. Instead, try telling the connection to disconnect. – Rob Kennedy Jul 23 '10 at 18:37
  • Ok - That worked!!!! Thanks for your help and **solution**. BUT - how can I give the vote to you? (you never made a formal answer). – M Schenkel Jul 23 '10 at 19:16
  • That's because I don't know how to set the response timeout for Indy components. Seems to me you figured that part out on your own. – Rob Kennedy Jul 23 '10 at 19:22
  • @Rob: another option is to have the TIdHTTP.OnWork event raise an exception, such as by calling SysUtils.Abort(), if the calling thread's Terminated property has been set to True. Calling Disconnect() from another thread context is another option, and has a similar effect by making Indy raise its own exception. – Remy Lebeau Jul 24 '10 at 06:33
  • I noticed a strange thing with Indy and Timeout. If I create the IdHTTP like that `TIdHTTP.Create;` the timeout (Read and Connect) will not work... But if I create the IdHTTP like that `TIdHTTP.Create(nil)`, the timeout works perfectly ! I missed something ? – Beny Sep 17 '12 at 15:32

2 Answers2

9

This doesn't answer the particular question above, but since this is where Google takes you if you search for "indy http timeout", I will mention here that you can set these properties:

TIdHTTP.ReadTimeout
TIdHTTP.ConnectTimeout
dan-gph
  • 16,301
  • 12
  • 61
  • 79
4

I eventually got the answer based on the comments of Rob Kennedy. I tried numerous times to contact him and request he make a "formal" answer so that I could give him the vote. Never heard back.

M Schenkel
  • 6,294
  • 12
  • 62
  • 107