Jak uniknąć błędu 10053 (WSAECONNABORTED), jeśli operacja HttpGet w Androidzie trwa zbyt długo?
Mam aplikację na Androida komunikującą się z aplikacją internetową Delphi 2006 za pomocą Indy 10 TIdHttpServer (dostarczany z Delphi 2006). Aplikacja Delphi generuje duży plik XML i służy temu. Generacja XML może trwać dłużej niż 5 minut.
Jeśli czas trwaniaGenerateXml()
jest więcej niż około 5 minut (*), wykrywam błąd 10053 wTIdHTTPResponseInfo.WriteContent
jeśli działa w IDE Delphi:
Socket Error # 10053 Software caused connection abort.
Jednak po stronie Androida nic nie jest wykrywane iHttpGet
-wywołanie trwa wiecznie.
Moje pytania to:
1.) Dlaczego otrzymuję błąd 10053 i jak mogę tego uniknąć? Wygląda na to, że android traci połączenie, alehttp.socket.timeout
jest ustawiony na nieskończony.
i
2.) Co mogę zrobić, aby wykryć taki błąd po stronie klienta (poza ustawieniem limitu czasu, który musiałby być zbyt duży, aby był użyteczny)? Czy mogę coś zrobić w TIdHttpServer.OnException?
Oto mój kod. Android - funkcja pobierania, która jest uruchamiana w AsyncTask:
protected static HttpEntity downloadEntity(String url) throws IOException {
HttpClient client = new DefaultHttpClient();
//Check because of Error 10053: but timeout is null -> infinite
Log.d("TAG", "http.socket.timeout: " + client.getParams().getParameter("http.socket.timeout"));
HttpGet get = new HttpGet(url);
HttpResponse response;
try {
//in case of Error 10053 the following call seems to last forever (in PlainSocketImpl.read)
response = client.execute(get);
} catch (ClientProtocolException e) {
//...
}
//...
return response.getEntity();
}
Implementacja Delphi TIdHttpServer.OnCommandGet:
procedure ServeXmlDoc(XmlDoc: IXMLDocument; ResponseInfo: TIdHTTPResponseInfo);
var
TempStream: TMemoryStream;
begin
ResponseInfo.ContentType := 'text/xml';
TempStream := TMemoryStream.Create;
XMLDoc.SaveToStream(TempStream);
ResponseInfo.FreeContentStream := True;
ResponseInfo.ContentStream := TempStream;
end;
procedure TMyService.HTTPServerCommandGet(AContext: TIdContext; RequestInfo: TIdHTTPRequestInfo;
ResponseInfo: TIdHTTPResponseInfo);
begin
Coinitialize(nil);
try
//...
ServeXmlDoc(GenerateXml(), ResponseInfo);
finally
CoUninitialize;
end;
end;
Edytować: (*) Przeprowadziłem dalsze testy i doświadczyłem błędu nawet w przypadkach, gdy cały proces trwał mniej niż 2 minuty.