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

Popular posts from this blog

windows - Single EXE to Install Python Standalone Executable for Easy Distribution -

c# - Access objects in UserControl from MainWindow in WPF -

javascript - How to name a jQuery function to make a browser's back button work? -