Skip to content

Commit

Permalink
Merge pull request #22 from cayque10/automatic-reconnection
Browse files Browse the repository at this point in the history
Automatic reconnection
  • Loading branch information
mateusvicente100 authored May 21, 2024
2 parents 996e2ec + 3fcd8b3 commit 289ce61
Show file tree
Hide file tree
Showing 8 changed files with 499 additions and 2,325 deletions.
4 changes: 3 additions & 1 deletion samples/Bird.Socket.Samples.dpr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ uses
Samples in 'src\Samples.pas' {FrmMainMenu},
Bird.Socket.Client.Consts in '..\src\Bird.Socket.Client.Consts.pas',
Bird.Socket.Client in '..\src\Bird.Socket.Client.pas',
Bird.Socket.Client.Types in '..\src\Bird.Socket.Client.Types.pas';
Bird.Socket.Client.Types in '..\src\Bird.Socket.Client.Types.pas',
Bird.Socket.Client.ConnectionMonitor.Interfaces in '..\src\Bird.Socket.Client.ConnectionMonitor.Interfaces.pas',
Bird.Socket.Client.ConnectionMonitor in '..\src\Bird.Socket.Client.ConnectionMonitor.pas';

{$R *.res}

Expand Down
445 changes: 222 additions & 223 deletions samples/Bird.Socket.Samples.dproj

Large diffs are not rendered by default.

Binary file modified samples/Bird.Socket.Samples.res
Binary file not shown.
2,081 changes: 0 additions & 2,081 deletions samples/src/Samples.dfm

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions samples/src/Samples.pas
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,22 @@ procedure TFrmMainMenu.Connect;
begin
try
FBirdSocket := TBirdSocketClient.New(edtServer.Text);

FBirdSocket.AddEventListener(TEventType.MESSAGE,
procedure(const AText: string)
begin
Log(AText);
end);

FBirdSocket
.AutoReconnect
.Active(True)
.Interval(20000);

FBirdSocket.Connect;

FBirdSocket.Send('Hello Server');

HandlerButtons(True);
except
on E:Exception do
Expand Down
41 changes: 41 additions & 0 deletions src/Bird.Socket.Client.ConnectionMonitor.Interfaces.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
unit Bird.Socket.Client.ConnectionMonitor.Interfaces;

interface

type

/// <summary>
/// Interface representing the connection monitor parameters.
/// </summary>
IBirdSocketClientConnectionMonitorParams = interface
['{CDEF540C-E21C-46B6-8551-894CF00661ED}']
/// <summary>
/// Sets the active status of the connection monitor.
/// </summary>
/// <param name="AValue">Boolean value indicating if the monitor should be active.</param>
/// <returns>The updated connection monitor parameters interface.</returns>
function Active(const AValue: Boolean): IBirdSocketClientConnectionMonitorParams;

/// <summary>
/// Sets the interval for the connection check.
/// </summary>
/// <param name="AValue">Interval value in milliseconds.</param>
/// <returns>The updated connection monitor parameters interface.</returns>
function Interval(const AValue: Integer): IBirdSocketClientConnectionMonitorParams;
end;

/// <summary>
/// Interface representing the connection monitor.
/// </summary>
IBirdSocketClientConnectionMonitor = interface
['{933093C3-20AB-4A31-8DA0-31F60EC57189}']
/// <summary>
/// Sets up auto-reconnect parameters for the connection monitor.
/// </summary>
/// <returns>The connection monitor parameters interface.</returns>
function AutoReconnect: IBirdSocketClientConnectionMonitorParams;
end;

implementation

end.
106 changes: 106 additions & 0 deletions src/Bird.Socket.Client.ConnectionMonitor.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
{
Class to monitor the connection status of a Bird Socket Client and attempt reconnection if the connection is lost.
}

unit Bird.Socket.Client.ConnectionMonitor;

interface

uses
System.Classes,
System.SysUtils;

type
TBirdSocketClientConnectionMonitor = class(TThread)
private
/// <summary>
/// Interval between connection status checks, in milliseconds.
/// </summary>
FInterval: Integer;
/// <summary>
/// Function to check the current connection status. Should return True if connected, False otherwise.
/// </summary>
FOnStatusCurrentConnection: TFunc<Boolean>;
/// <summary>
/// Procedure to attempt reconnection if the connection is lost.
/// </summary>
FOnReconnect: TProc;
/// <summary>
/// Indicates if the monitor is currently trying to reconnect.
/// </summary>
FTryingConnect: Boolean;
protected
/// <summary>
/// Main execution method for the thread. Periodically checks the connection status and attempts reconnection if necessary.
/// </summary>
procedure Execute; override;
public
/// <summary>
/// Creates an instance of the connection monitor thread.
/// </summary>
/// <param name="ACreatedSuspended">Indicates if the thread should be created in a suspended state.</param>
/// <param name="AInterval">Interval between connection status checks, in milliseconds.</param>
/// <param name="AOnStatusCurrentConnection">Function to check the current connection status.</param>
/// <param name="AOnReconnect">Procedure to attempt reconnection if the connection is lost.</param>
constructor Create(const ACreatedSuspended: Boolean; const AInterval: Integer;
const AOnStatusCurrentConnection: TFunc<Boolean>; const AOnReconnect: TProc);
end;

implementation

uses
System.DateUtils;

{ TBirdSocketClientConnectionMonitor }

constructor TBirdSocketClientConnectionMonitor.Create(const ACreatedSuspended: Boolean; const AInterval: Integer;
const AOnStatusCurrentConnection: TFunc<Boolean>; const AOnReconnect: TProc);
begin
inherited Create(ACreatedSuspended);
FInterval := AInterval;
FOnStatusCurrentConnection := AOnStatusCurrentConnection;
FOnReconnect := AOnReconnect;
FTryingConnect := False;
FreeOnTerminate := False;
end;

procedure TBirdSocketClientConnectionMonitor.Execute;
var
LStatusConnection: Boolean;
lStart: TDateTime;
begin

while not terminated do
begin
lStart := Now;

while (not terminated) and (MilliSecondsBetween(Now, lStart) < FInterval) do
Sleep(100);

if not Assigned(FOnStatusCurrentConnection) then
raise Exception.Create('The connection status check event has not been set!');

if not Assigned(FOnReconnect) then
raise Exception.Create('The reconnect event has not been set!');

LStatusConnection := FOnStatusCurrentConnection;

if not terminated and not FTryingConnect and not LStatusConnection then
begin
FTryingConnect := True;
try
TThread.Synchronize(TThread.Current,
procedure
begin
FOnReconnect;
end);
finally
FTryingConnect := False;
end;
end;

end;

end;

end.
Loading

0 comments on commit 289ce61

Please sign in to comment.