fpc/packages/fcl-process/examples/threadedipc.lpr
2017-08-15 09:55:18 +00:00

112 lines
2.7 KiB
ObjectPascal

program ThreadedIPC;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}cthreads,{$ENDIF}
SysUtils, Classes, Math, FGL, SimpleIPC;
const
ServerUniqueID = '39693DC0-BD8B-4AAD-9D9B-387D37CD59FD';
ServerTimeout = 5000;
ClientDelayMin = 500;
ClientDelayMax = 3000;
ClientCount = 10;
var
ServerThreaded: Boolean = True;
type
TServerMessageHandler = class
public
procedure HandleMessage(Sender: TObject);
procedure HandleMessageQueued(Sender: TObject);
end;
procedure TServerMessageHandler.HandleMessage(Sender: TObject);
begin
WriteLn(TSimpleIPCServer(Sender).StringMessage);
end;
procedure TServerMessageHandler.HandleMessageQueued(Sender: TObject);
begin
TSimpleIPCServer(Sender).ReadMessage;
end;
procedure ServerWorker;
var
Server: TSimpleIPCServer;
MessageHandler: TServerMessageHandler;
begin
WriteLn(Format('Starting server #%x', [GetThreadID]));
MessageHandler := TServerMessageHandler.Create;
Server := TSimpleIPCServer.Create(nil);
try
Server.ServerID := ServerUniqueID;
Server.Global := True;
Server.OnMessage := @MessageHandler.HandleMessage;
Server.OnMessageQueued := @MessageHandler.HandleMessageQueued;
Server.StartServer(ServerThreaded);
if ServerThreaded then
Sleep(ServerTimeout)
else
while Server.PeekMessage(ServerTimeout, True) do ;
except on E: Exception do
WriteLn('Server error: ' + E.Message);
end;
Server.Free;
MessageHandler.Free;
WriteLn(Format('Finished server #%x', [GetThreadID]));
end;
procedure ClientWorker;
var
Client: TSimpleIPCClient;
Message: String;
begin
WriteLn(Format('Starting client #%x', [GetThreadID]));
Client := TSimpleIPCClient.Create(nil);
try
Client.ServerID := ServerUniqueID;
while not Client.ServerRunning do
Sleep(100);
Client.Active := True;
Sleep(RandomRange(ClientDelayMin, ClientDelayMax));
Message := Format('Hello from client #%x', [GetThreadID]);
Client.SendStringMessage(Message);
except on E: Exception do
WriteLn('Client error: ' + E.Message);
end;
Client.Free;
WriteLn(Format('Finished client #%x', [GetThreadID]));
end;
type
TThreadList = specialize TFPGObjectList<TThread>;
var
I: Integer;
Thread: TThread;
Threads: TThreadList;
begin
Randomize;
WriteLn('Threaded server: ' + BoolToStr(ServerThreaded, 'YES', 'NO'));
Threads := TThreadList.Create(True);
try
Threads.Add(TThread.CreateAnonymousThread(@ServerWorker));
for I := 1 to ClientCount do
Threads.Add(TThread.CreateAnonymousThread(@ClientWorker));
for Thread in Threads do
begin
Thread.FreeOnTerminate := False;
Thread.Start;
end;
for Thread in Threads do
Thread.WaitFor;
finally
Threads.Free;
end;
end.