postmanecho.pp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. program PostManEcho;
  2. {$mode objfpc}{$H+}
  3. uses
  4. {$IFDEF UNIX}
  5. cthreads,
  6. {$ENDIF}
  7. SysUtils,
  8. Classes,
  9. opensslsockets,
  10. fpwebsocketclient,
  11. fpwebsocket;
  12. type
  13. TWebSocketDemo = class
  14. private
  15. FClient: TWebsocketClient;
  16. FConnected: Boolean;
  17. procedure HandleConnect(Sender: TObject);
  18. procedure HandleDisconnect(Sender: TObject);
  19. procedure HandleMessageReceived(Sender: TObject; const AMessage: TWSMessage);
  20. public
  21. constructor Create;
  22. destructor Destroy; override;
  23. procedure Connect(const AHost: string; APort: Integer; const AResource: string);
  24. procedure Disconnect;
  25. procedure Send(const AMessage: string);
  26. procedure WaitForMessages(ASeconds: Integer);
  27. end;
  28. { TWebSocketDemo }
  29. constructor TWebSocketDemo.Create;
  30. var
  31. LMessagePump: TWSThreadMessagePump;
  32. begin
  33. inherited Create;
  34. FConnected := False;
  35. // Create message pump for async message handling
  36. LMessagePump := TWSThreadMessagePump.Create(nil);
  37. LMessagePump.Interval := 50; // Check every 50ms
  38. // Create client
  39. FClient := TWebsocketClient.Create(nil);
  40. FClient.MessagePump := LMessagePump;
  41. FClient.ConnectTimeout := 10000;
  42. FClient.CheckTimeOut := 100;
  43. // Wire events
  44. FClient.OnConnect := @HandleConnect;
  45. FClient.OnDisconnect := @HandleDisconnect;
  46. FClient.OnMessageReceived := @HandleMessageReceived;
  47. end;
  48. destructor TWebSocketDemo.Destroy;
  49. begin
  50. WriteLn('Destroying WebSocketDemo...');
  51. // Disconnect if still connected
  52. if FConnected then
  53. Disconnect;
  54. // Free message pump first
  55. if Assigned(FClient.MessagePump) then
  56. begin
  57. WriteLn(' Freeing message pump...');
  58. FClient.MessagePump.Free;
  59. end;
  60. // Free client
  61. WriteLn(' Freeing client...');
  62. FClient.Free;
  63. WriteLn(' Done.');
  64. inherited;
  65. end;
  66. procedure TWebSocketDemo.HandleConnect(Sender: TObject);
  67. begin
  68. FConnected := True;
  69. WriteLn('Connected!');
  70. end;
  71. procedure TWebSocketDemo.HandleDisconnect(Sender: TObject);
  72. begin
  73. FConnected := False;
  74. WriteLn('Disconnected!');
  75. end;
  76. procedure TWebSocketDemo.HandleMessageReceived(Sender: TObject; const AMessage: TWSMessage);
  77. begin
  78. if AMessage.IsText then
  79. WriteLn('Received: ', AMessage.AsString)
  80. else
  81. WriteLn('Received binary data: ', Length(AMessage.PayLoad), ' bytes');
  82. end;
  83. procedure TWebSocketDemo.Connect(const AHost: string; APort: Integer; const AResource: string);
  84. begin
  85. WriteLn('Connecting to ', AHost, ':', APort, AResource);
  86. FClient.HostName := AHost;
  87. FClient.Port := APort;
  88. FClient.Resource := AResource;
  89. FClient.UseSSL := (APort = 443);
  90. // Start message pump
  91. if Assigned(FClient.MessagePump) then
  92. begin
  93. WriteLn('Starting message pump...');
  94. FClient.MessagePump.Execute;
  95. end;
  96. // Connect
  97. FClient.Connect;
  98. end;
  99. procedure TWebSocketDemo.Disconnect;
  100. begin
  101. if not FClient.Active then
  102. Exit;
  103. WriteLn('Disconnecting...');
  104. // Stop message pump first
  105. if Assigned(FClient.MessagePump) then
  106. begin
  107. try
  108. FClient.MessagePump.Terminate;
  109. except
  110. // Ignore
  111. end;
  112. end;
  113. FClient.Disconnect;
  114. end;
  115. procedure TWebSocketDemo.WaitForMessages(ASeconds: Integer);
  116. var
  117. I: Integer;
  118. begin
  119. WriteLn('Waiting ', ASeconds, ' seconds for messages...');
  120. for I := 1 to ASeconds do
  121. begin
  122. Sleep(1000);
  123. Write('.');
  124. end;
  125. WriteLn;
  126. end;
  127. procedure TWebSocketDemo.Send(const AMessage: string);
  128. begin
  129. WriteLn('Sending: ', AMessage);
  130. FClient.SendMessage(AMessage);
  131. end;
  132. var
  133. Demo: TWebSocketDemo;
  134. begin
  135. WriteLn('=== Postman echo Demo ===');
  136. WriteLn;
  137. Demo := TWebSocketDemo.Create;
  138. try
  139. // Connect to a public WebSocket echo server
  140. // For testing, we'll just connect briefly
  141. try
  142. // Use a working echo server (wss://ws.postman-echo.com/raw)
  143. Demo.Connect('ws.postman-echo.com', 443, '/raw');
  144. // Wait for connection
  145. Sleep(2000);
  146. // Send a test message
  147. Demo.Send('Hello from FPC WebSocket Leak Demo!');
  148. // Wait for echo response
  149. Demo.WaitForMessages(3);
  150. except
  151. on E: Exception do
  152. WriteLn('Connection error (expected if server unavailable): ', E.Message);
  153. end;
  154. finally
  155. Demo.Free;
  156. end;
  157. WriteLn;
  158. WriteLn('Demo complete.');
  159. end.