我还没有在德尔福编程一段时间,坦率地说我不会想到...... 在这里,我拼命想找到关于这个问题的一些信息,现在它很稀缺,我找不到任何东西。所以也许你们可以帮助我。
目前我的应用程序使用Synapse库进行HTTP调用,但不允许设置超时。通常,这不是一个大问题,但现在我必须有一个超时来很好地处理任何连接问题。
我正在寻找的是一个库(同步或非同步),它允许HTTP请求对于没有可见或隐藏延迟的用户绝对透明。我现在不能立即杀死一个线程,并且可能会有许多频繁请求没有响应的服务器,这没有用。
编辑:谢谢大家的回答!答案 0 :(得分:3)
在进行网络通信时,您始终需要考虑延迟和超时。你可以获得最接近的IMHO是将网络通信放在一个线程中。然后你可以检查线程是否在所需的时间内完成,如果不是让它完成,但忽略结果(没有安全的方法来中止线程)。这还有一个额外的好处:您现在可以使用更容易阅读的同步网络调用。
答案 1 :(得分:2)
在synapse中,TSynaClient对象可以使用THttpSend对象的超时时间。所以你需要做的就是调整超时(假设你使用标准函数)是复制你使用的函数,添加一个新参数并将Timeout设置为你需要的。例如:
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;
Synapse默认为超时5000,如果您等待足够长时间,则会超时。由于其紧密包含,突触在线程中运行完美。
答案 2 :(得分:1)
[仅限于D2010工作]
您可以使用MSXML发送客户端请求(将msxml
和ole2
添加到您的uses
子句中。诀窍是使用IServerXMLHTTPRequest而不是IXMLHTTPRequest,因为前者允许指定超时。下面的代码显示了线程的Execute()
方法:
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;
我最近发现了一种非常讨厌的MSXML技术行为,如果后续发送的URL保持不变,则不会重新发送GET
个请求。换句话说,客户端正在缓存GET
个请求。 POST
不会发生这种情况。
显然,一旦超时发生,Execute
方法就完成了,线程就被清理了。
答案 3 :(得分:0)
可以将Synapse配置为在发生网络错误时引发异常。
<强> RaiseExcept 强>
检查http://synapse.ararat.cz/doc/help/blcksock.TBlockSocket.html#RaiseExcept:
如果为True,则会出现winsock错误 例外。否则设置 只有LastError值,您必须 从你的程序检查它!默认 值为假。