threadedipc.lpr 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. program ThreadedIPC;
  2. {$mode objfpc}{$H+}
  3. uses
  4. {$IFDEF UNIX}cthreads,{$ENDIF}
  5. SysUtils, Classes, Math, FGL, SimpleIPC;
  6. const
  7. ServerUniqueID = '39693DC0-BD8B-4AAD-9D9B-387D37CD59FD';
  8. ServerTimeout = 5000;
  9. ClientDelayMin = 500;
  10. ClientDelayMax = 3000;
  11. ClientCount = 10;
  12. var
  13. ServerThreaded: Boolean = True;
  14. type
  15. TServerMessageHandler = class
  16. public
  17. procedure HandleMessage(Sender: TObject);
  18. procedure HandleMessageQueued(Sender: TObject);
  19. end;
  20. procedure TServerMessageHandler.HandleMessage(Sender: TObject);
  21. begin
  22. WriteLn(TSimpleIPCServer(Sender).StringMessage);
  23. end;
  24. procedure TServerMessageHandler.HandleMessageQueued(Sender: TObject);
  25. begin
  26. TSimpleIPCServer(Sender).ReadMessage;
  27. end;
  28. procedure ServerWorker;
  29. var
  30. Server: TSimpleIPCServer;
  31. MessageHandler: TServerMessageHandler;
  32. begin
  33. WriteLn(Format('Starting server #%x', [GetThreadID]));
  34. MessageHandler := TServerMessageHandler.Create;
  35. Server := TSimpleIPCServer.Create(nil);
  36. try
  37. Server.ServerID := ServerUniqueID;
  38. Server.Global := True;
  39. Server.OnMessage := @MessageHandler.HandleMessage;
  40. Server.OnMessageQueued := @MessageHandler.HandleMessageQueued;
  41. Server.StartServer(ServerThreaded);
  42. if ServerThreaded then
  43. Sleep(ServerTimeout)
  44. else
  45. while Server.PeekMessage(ServerTimeout, True) do ;
  46. except on E: Exception do
  47. WriteLn('Server error: ' + E.Message);
  48. end;
  49. Server.Free;
  50. MessageHandler.Free;
  51. WriteLn(Format('Finished server #%x', [GetThreadID]));
  52. end;
  53. procedure ClientWorker;
  54. var
  55. Client: TSimpleIPCClient;
  56. Message: String;
  57. begin
  58. WriteLn(Format('Starting client #%x', [GetThreadID]));
  59. Client := TSimpleIPCClient.Create(nil);
  60. try
  61. Client.ServerID := ServerUniqueID;
  62. while not Client.ServerRunning do
  63. Sleep(100);
  64. Client.Active := True;
  65. Sleep(RandomRange(ClientDelayMin, ClientDelayMax));
  66. Message := Format('Hello from client #%x', [GetThreadID]);
  67. Client.SendStringMessage(Message);
  68. except on E: Exception do
  69. WriteLn('Client error: ' + E.Message);
  70. end;
  71. Client.Free;
  72. WriteLn(Format('Finished client #%x', [GetThreadID]));
  73. end;
  74. type
  75. TThreadList = specialize TFPGObjectList<TThread>;
  76. var
  77. I: Integer;
  78. Thread: TThread;
  79. Threads: TThreadList;
  80. begin
  81. Randomize;
  82. WriteLn('Threaded server: ' + BoolToStr(ServerThreaded, 'YES', 'NO'));
  83. Threads := TThreadList.Create(True);
  84. try
  85. Threads.Add(TThread.CreateAnonymousThread(@ServerWorker));
  86. for I := 1 to ClientCount do
  87. Threads.Add(TThread.CreateAnonymousThread(@ClientWorker));
  88. for Thread in Threads do
  89. begin
  90. Thread.FreeOnTerminate := False;
  91. Thread.Start;
  92. end;
  93. for Thread in Threads do
  94. Thread.WaitFor;
  95. finally
  96. Threads.Free;
  97. end;
  98. end.