Get the source code on Github
This example uses a Delphi 2009 VCL application with a main form, which contains only one visual component, a TMemo named “MemoLog”.
Client and server are both started in the FormCreate event.
procedure TServerPushExampleForm.FormCreate(Sender: TObject); begin ExampleServer := TMyPushServer.Create; ExampleServer.DefaultPort := 8088; ExampleServer.Active := True; ExampleClient := TMyPushClientThread.Create('localhost', 8088, MemoLog.Lines); end;
Server
The server code uses a TIdTCPCustomServer subclass which waits for a random time and then sends a string to the client.
function TMyPushServer.DoExecute(AContext: TIdContext): Boolean; begin Result := inherited; // simulate hard work Sleep(Random(3000)); AContext.Connection.IOHandler.WriteLn( 'Completed at ' + TimeToStr(Now), IndyTextEncoding_UTF8); end;
Client
The client code uses a TThread subclass to run asynchronously without blocking the main VCL thread. It contains a private TIdTCPClient instance, and periodically tries to receive a string from the connection.
... S := TCPClient.IOHandler.ReadLn(IndyTextEncoding_UTF8); ...
Full Delphi Form Code
Below is the full code for the example main form.
unit Unit1; interface uses IdCustomTCPServer, IdTCPClient, IdContext, SysUtils, Classes, Forms, StdCtrls, Controls; type TMyPushClientThread = class(TThread) private TCPClient: TIdTCPClient; FLog: TStrings; public constructor Create(AHost: string; APort: Word; ALog: TStrings); destructor Destroy; override; procedure Execute; override; end; TMyPushServer = class (TIdCustomTCPServer) protected function DoExecute(AContext: TIdContext): Boolean; override; end; TServerPushExampleForm = class(TForm) MemoLog: TMemo; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private ExampleClient: TMyPushClientThread; ExampleServer: TMyPushServer; end; var ServerPushExampleForm: TServerPushExampleForm; implementation uses IdGlobal; {$R *.dfm} procedure TServerPushExampleForm.FormCreate(Sender: TObject); begin ExampleServer := TMyPushServer.Create; ExampleServer.DefaultPort := 8088; ExampleServer.Active := True; ExampleClient := TMyPushClientThread.Create('localhost', 8088, MemoLog.Lines); end; procedure TServerPushExampleForm.FormDestroy(Sender: TObject); begin ExampleServer.Free; ExampleClient.Terminate; ExampleClient.WaitFor; ExampleClient.Free; end; { TMyPushServer } function TMyPushServer.DoExecute(AContext: TIdContext): Boolean; begin Result := inherited; // simulate hard work Sleep(Random(3000)); AContext.Connection.IOHandler.WriteLn( 'Completed at ' + TimeToStr(Now), IndyTextEncoding_UTF8); end; { TMyPushClientThread } constructor TMyPushClientThread.Create(AHost: string; APort: Word; ALog: TStrings); begin inherited Create(False); FLog := ALog; TCPClient := TIdTCPClient.Create; TCPClient.Host := AHost; TCPClient.Port := APort; TCPClient.ReadTimeout := 500; end; destructor TMyPushClientThread.Destroy; begin TCPClient.Free; inherited; end; procedure TMyPushClientThread.Execute; var S: string; begin TCPClient.Connect; while not Terminated do begin S := TCPClient.IOHandler.ReadLn(IndyTextEncoding_UTF8); if not TCPClient.IOHandler.ReadLnTimedout then begin TThread.Queue(nil, procedure begin FLog.Append(S); end); end; end; TCPClient.Disconnect; end; end.
Discover more from Habarisoft Blog
Subscribe to get the latest posts sent to your email.