delphi - How to avoid getting an error 10053 (WSAECONNABORTED) if a HttpGet operation in Android is lasting too long? -


i have android application communicating delphi 2006 web service application using indy 10 tidhttpserver (coming delphi 2006). delphi application generates big xml file , serves this. xml generation may last more 5 minutes.

if duration of generatexml() more 5 minutes (*), detect error 10053 in tidhttpresponseinfo.writecontent if running in delphi ide:

socket error # 10053 software caused connection abort. 

however, on android side nothing detected , httpget-call lasts forever.

my questions are:

1.) why error 10053 , how can avoid it? seems android times out connection, http.socket.timeout set infinite.

and

2.) can detect such error on client side (other setting timeout, have big useful)? can in tidhttpserver.onexception?

here code. android - download function, run inside asynctask:

protected static httpentity downloadentity(string url) throws ioexception {     httpclient client = new defaulthttpclient();        //check because of error 10053: timeout null -> infinite     log.d("tag", "http.socket.timeout: " + client.getparams().getparameter("http.socket.timeout"));      httpget = new httpget(url);     httpresponse response;     try {         //in case of error 10053 following call seems last forever (in plainsocketimpl.read)         response = client.execute(get);     } catch (clientprotocolexception e) {         //...     }      //...      return response.getentity();   }    

delphi implementation of 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);             couninitialize;     end; end; 

edit: (*) have done further testing , experienced error in cases whole process had duration of under 2 minutes.

something between android , server, such firewall/router, cutting connection after idle long. should try enabling tcp keep-alives avoid that.

on other hand, kind of situation http 1.1's chunked transfer encoding designed handle (assuming using http 1.1 begin with). instead of waiting 5 minutes entire xml generated in full before sending client, should send xml in pieces being generated. not keep connection active, reduces server's memory footprint since doesn't have store entire xml in memory @ 1 time.

tidhttpserver not (yet) natively support sending chunked responses (but tidhttp support receiving chunked responses), not difficult implement manually. write custom tstream derived class , overwrite virtual write() method (or use indy's tideventstream class) write data http client using format outlined in rfc 2616 section 3.6.1. that, can have servexmldoc() set responseinfo.transferencoding property 'chunked' , call responseinfo.writeheader() method without setting either responseinfo.contenttext or responseinfo.contentstream properties, pass custom stream ixmldocument.savetostream() finish writing response data after headers. example:

type   tmychunkedstream = class(tstream)   private     fio: tidiohandler;   public     constructor create(aio: tidiohandler);     function write(const buffer; count: longint): longint; override;     procedure finished;     ...   end;  constructor tmychunkedstream.create(aio: tidiohandler); begin   inherited create;   fio := aio; end;  function tmychunkedstream.write(const buffer; count: longint): longint; override; begin   if count > 0   begin     fio.writeln(inttohex(count, 1));     fio.write(rawtobytes(buffer, count));     fio.writeln;   end;   result := count; end;  procedure tmychunkedstream.finished; begin   fio.writeln('0');   fio.writeln; end; 

procedure servexmldoc(xmldoc: ixmldocument; responseinfo: tidhttpresponseinfo); var   tempstream: tmychunkedstream; begin   responseinfo.contenttype := 'text/xml';   responseinfo.transferencoding := 'chunked';   responseinfo.writeheader;    tempstream := tmychunkedstream.create(responseinfo.connection.iohandler);   try     xmldoc.savetostream(tempstream);     tempstream.finished;       tempstream.free;   end; end; 

if, on other hand, bulk of waiting inside of generatexml() , not in xmldoc.savetostream(), need rethink server design, , figure out way speed generatexml(), or rid of ixmldocument , create xml manually can send using responseinfo.connection.iohandler creating xml content.


Comments

Popular posts from this blog

html - How to style widget with post count different than without post count -

How to remove text and logo OR add Overflow on Android ActionBar using AppCompat on API 8? -

javascript - storing input from prompt in array and displaying the array -