我有一个应用程序,它一天会发出数千个HTTP请求。 为了获得最佳性能,我决定只创建一次IdHTTP对象,并对所有请求使用相同的对象。 这是问题开始的地方。在为每个请求创建一个IdHTTP时,一切正常。 该代码非常基本:
constructor HTTPThread.Create;
begin
inherited Create(false);
httpObject:= TIdHTTP.Create(Nil);
sslObject:= TIdSSLIOHandlerSocketOpenSSL.Create(Nil);
sslObject.SSLOptions.Method:= sslvTLSv1_2;
httpObject.IOHandler:= sslObject;
httpObject.Request.Accept:= frmHTTPRequests.Edit1.Text;
httpObject.Request.UserAgent:= frmHTTPRequests.Edit3.Text;
httpObject.ReadTimeout:= 15000;
httpObject.HandleRedirects:= true;
FreeOnTerminate:= true;
OnTerminate:= TerminateProc;
end;
procedure HTTPThread.DoRequests;
var
htmlSource: string;
begin
try
htmlSource:= httpObject.Get(Link);
//a bunch of other stuff with HTML source
except
on E : Exception do
Synchronize(procedure
begin
errorList.Add(E.Message);
errorList.SaveToFile('Error.txt');
end);
end;
end;
除了保存Error.txt文件以观察发生了什么以外,我创建了此文件... 有时,对于前1k个请求,代码运行良好,有时对于前2k个请求,代码会有所不同。突然,它开始在TXT文件上写入相同的错误:
连接被同级重置。 domain.com-套接字错误#10054
我试图断开httpObject的连接,尝试了httpObject.Request.Clear,似乎没有任何作用。 有没有机会做这项工作?
答案 0 :(得分:1)
由于某些原因,当服务器用Connection reset by peer
响应时,Indy不会关闭套接字,因此您需要手动进行操作。
procedure HTTPThread.DoRequests;
const
MAX_TRIES_COUNT = 5;
var
htmlSource: string;
TriesCount: Integer;
begin
TriesCount := 0;
repeat
try
htmlSource:= httpObject.Get(Link);
//a bunch of other stuff with HTML source
except
on E : Exception do
begin
if E.Message.Contains('by peer') then
begin
httpObject.Disconnect;
// Try to solve network connection issues
Continue;
end;
else
begin
// Some other error handlers
end;
end;
inc(TriesCount);
end;
until (httpObject.ResponseCode = 200) or (TriesCount > MAX_TRIES_COUNT);
end;
P.S。我不建议您使用Synchronize()
进行线程同步。尝试改用TCriticalSection或TMonitor。