indy - Delphi, Indy10, How to properly stop and cleanup a readln on a continuous stream -
using delphi 2010 , indy10
i attempting read server sent events delphi. have managed create thread subscribe connection on server (python/flask) , capture events. thread needed because http.get blocking forever. realize entire protocol not implemented, interested in receiving short strings broadcast server. following code works, have not been able figure out how cleanly stop thread , free http_client , stream when stopping program.
on server side ""an existing connection forcibly close remote host"" , program indicating memory leaks. have tried many different combinations of trying close http connection @ various points (onterminate,destroy) , can't work. insights or examples appreciated.
here relevant code have far:
tssethread = class(tthread) private url: string; stream: tmemorystream; http_client: tidhttp; procedure doonwork(asender: tobject; aworkmode: tworkmode; aworkcount: int64); public constructor create(createsuspended: boolean; url: string); procedure execute; override; end; constructor tssethread.create(createsuspended: boolean; url: string); begin inherited create(createsuspended); // sending false here self.freeonterminate := false; self.url := url; end; procedure tssethread.execute; begin inherited; try stream := tmemorystream.create; http_client := tidhttp.create(nil); http_client.onwork := doonwork; http_client.request.cachecontrol := 'no-cache'; http_client.request.accept := 'text/event-stream'; http_client.response.keepalive := true; while not terminated try http_client.get(self.url,stream); except on e: exception begin try http_client.disconnect; except end; if http_client.iohandler <> nil http_client.iohandler.inputbuffer.clear; sleep(3000); end; end; http_client.free; stream.free; end; end; procedure tssethread.doonwork(asender: tobject; aworkmode: tworkmode; aworkcount: int64); var msg: string; begin if self.terminated exit; setstring(msg,pansichar(stream.memory),stream.size); stream.position := 0; if pos('data:',msg) > 0 begin // handle msg here. works fine. end; end;
in onwork
event handler, when thread's terminated
property true, raise exception (such calling sysutils.abort()
) instead of calling exit
. exception abort http request , close connection, propegate execute()
, catch , check terminated
again break while
loop , let finally
block free tidhttp
object before exiting execute()
terminate thread.
procedure tssethread.doonwork(asender: tobject; aworkmode: tworkmode; aworkcount: int64); var msg: string; begin //if self.terminated exit; if self.terminated sysutils.abort; ... end;
Comments
Post a Comment