How to make an HTTP request in a separate thread with a timeout?

I did not program in Delphi for some time and, frankly, did not think that I would ever have to ... Here I am, desperately trying to find some information on this issue, and now it is so meager, I can’t do anything to find. So maybe you guys could help me.

Currently, my application uses the Synapse library to make HTTP calls, but does not allow a timeout. This is usually not a big problem, but now I absolutely must have a timeout to deal with any connection problems.

I'm looking for a library (synchronously or not) that will make HTTP requests completely transparent to the user without visible or hidden delays. I can’t immediately kill the thread right now, and with the possibility of many frequent requests to a server that does not respond, this is not good.

EDIT: Thank you all for your answers!

+4
source share
4 answers

When implementing network communication, it is always necessary to consider delays and timeouts. Closest you can get IMHO to bind a network connection in a stream. You can then check to see if the thread ends at the right time, and if not just finishing, but ignore the result (there is no safe way to interrupt the thread). This has the added benefit of: now you can simply use synchronous network calls, which are much easier to read.

+3
source

In synapse, a timeout is available from TSynaClient , which THttpSend rejects. So, all you have to do to set the timeout (provided that you use the standard functions) is to copy the function you use, add a new parameter and set the timeout to what you need. For instance:

function HttpGetTextTimeout(const URL: string; const Response: TStrings; const Timeout:integer): Boolean; var HTTP: THTTPSend; begin HTTP := THTTPSend.Create; try HTTP.Timeout := Timeout; Result := HTTP.HTTPMethod('GET', URL); if Result then Response.LoadFromStream(HTTP.Document); finally HTTP.Free; end; end; 

The default syntax is 5000 timeout and makes a timeout if you wait long enough. Since it is tightly folded, the synapse works fine in streams.

+2
source

[It is known that only works with D2010]

You can use MSXML to send client requests (add msxml and ole2 to the uses ). The trick is to use IServerXMLHTTPRequest, not IXMLHTTPRequest, since the former allows you to specify timeouts. The code below shows the Execute() method of a thread:

 procedure TClientSendThread.Execute; const LResolveTimeoutMilliseconds = 2000; LConnectTimeoutMilliseconds = 5000; LSendTimeoutMilliseconds = 5000; LReceiveTimeoutMilliseconds = 10000; var LHTTPServer: IServerXMLHTTPRequest; LDataStream: TMemoryStream; LData: OleVariant; begin {Needed because this is inside a thread.} CoInitialize(nil); LDataStream := TMemoryStream.Create; try {Populate ....LDataStream...} LData := MemoryStreamToOleVariant(LDataStream); LHTTPServer := CreateOleObject('MSXML2.ServerXMLHTTP.3.0') as IServerXMLHTTPRequest; LHTTPServer.setTimeouts( LResolveTimeoutMilliseconds, LConnectTimeoutMilliseconds, LSendTimeoutMilliseconds, LReceiveTimeoutMilliseconds ); LHTTPServer.open('POST', URL, False, 0, 0); LHTTPServer.send(LData); FAnswer := LHTTPServer.responseText; finally FreeAndNil(LDataStream); CoUninitialize; end; end; 

I recently discovered the extremely annoying behavior of this MSXML method, in which GET requests will not be resubmitted if the URL remains unchanged for subsequent submissions; in other words, the client caches GET requests. This does not happen with POST .

Obviously, after the timeout expires, the Execute method terminates and the thread clears.

+1
source

Synapse can be configured to throw an exception when network errors occur.

Raiseexcept

Check out http://synapse.ararat.cz/doc/help/blcksock.TBlockSocket.html#RaiseExcept :

If True, winsock errors raise an exception. Otherwise, LastError is set, and you must check it from your program! The default value is False.

0
source

Source: https://habr.com/ru/post/1304437/


All Articles