Skip to content

Instantly share code, notes, and snippets.

@Coldzer0
Created October 25, 2021 12:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Coldzer0/8c98a02721979abe116c9089791f55e4 to your computer and use it in GitHub Desktop.
Save Coldzer0/8c98a02721979abe116c9089791f55e4 to your computer and use it in GitHub Desktop.
mORMot2 Async Client Demo
Program AgentOne;
Uses
{$IfDef windows}
windows,
{$Else}
cthreads,
BaseUnix,
{$EndIf}
//mormot.core.fpcx64mm, // Error : mormot.core.fpcx64mm.pas(2463,36) Error: identifier idents no member "PeakBytes"
SysUtils,
mormot.net.async,
mormot.net.sock,
mormot.net.client,
mormot.core.os,
mormot.core.base,
mormot.core.buffers,
mormot.core.rtti,
mormot.core.threads,
mormot.core.Text,
mormot.core.log;
Type
{ TNewConnection }
TNewConnection = Class(TAsyncConnection)
Protected
Function OnLastOperationIdle(nowsec: TAsyncConnectionSec): Boolean; Override;
Function OnRead: TPollAsyncSocketOnReadWrite; Override;
Procedure OnClose; Override;
Procedure AfterCreate; Override;
Procedure BeforeDestroy; Override;
End;
{ TFastClient }
TFastClient = Class(TAsyncClient)
Private
LogFamily: TSynLogFamily;
Procedure Connect();
Protected
Function ConnectionCreate(aSocket: TNetSocket; Const aRemoteIp: RawUtf8; out aConnection: TAsyncConnection): Boolean; Override;
Public
Constructor Create(Const aRemoteHost, aTCPPort: RawUtf8); Reintroduce;
// shutdown and finalize
Destructor Destroy; Override;
End;
Var
AsyncThreads: TFastClient; // Async Threads for Read & Write
Function TNewConnection.OnLastOperationIdle(nowsec: TAsyncConnectionSec): Boolean;
Begin
Owner.WriteString(self, 'HI_Server');
Owner.log.Add.log(sllInfo, 'LastOperationIdle % ', [Handle], self);
Result := False;
End;
// This one never called ?!!!
Function TNewConnection.OnRead: TPollAsyncSocketOnReadWrite;
Begin
Result := soContinue;
Owner.Write(self, fRd.Buffer, fRd.Len);
Owner.log.Add.log(sllServer, 'OnRead From Server - Received Data Len [%]', [fRd.Len], self);
fRd.Reset;
End;
Procedure TNewConnection.OnClose;
Begin
Owner.log.Add.log(sllWarning, 'OnClose %', [Handle], self);
End;
Procedure TNewConnection.AfterCreate;
Begin
fLockMax := True;
Inherited AfterCreate;
End;
Procedure TNewConnection.BeforeDestroy;
Begin
Inherited BeforeDestroy;
End;
{ TFastClient }
Function TFastClient.ConnectionCreate(aSocket: TNetSocket; Const aRemoteIp: RawUtf8; out aConnection: TAsyncConnection): Boolean;
Var
log: ISynLog;
len: Integer;
Begin
If Terminated Then
Exit(False);
log := fLog.Enter('ConnectionCreate(%)', [PtrUInt(aSocket)], self);
aConnection := nil;
aSocket.MakeBlocking;
aConnection := TNewConnection.Create(self, aRemoteIp);
If Not Inherited ConnectionAdd(aSocket, aConnection) Then
Begin
FreeAndNilSafe(aConnection);
log.log(sllWarning, 'inherited %.ConnectionAdd(%) failed', [PtrUInt(aSocket)], self);
exit(False);
End;
WriteString(aConnection, 'Echo_Server');
Result := True;
End;
Constructor TFastClient.Create(Const aRemoteHost, aTCPPort: RawUtf8);
Begin
LogFamily := TSynLog.Family;
LogFamily.Level := LOG_VERBOSE;
LogFamily.PerThreadLog := ptIdentifiedInOnFile;
LogFamily.EchoToConsole := LOG_VERBOSE;
Self.LastOperationIdleSeconds := 15;
Inherited Create(aRemoteHost, aTCPPort, 0, 10, nil, nil, TNewConnection,
'FastClient', LogFamily.SynLogClass, [acoVerboseLog, acoDebugReadWriteLog], 2);
End;
Destructor TFastClient.Destroy;
Begin
Inherited Destroy;
End;
Procedure TFastClient.Connect();
Var
res: TNetResult;
client: TNetSocket;
connection: TAsyncConnection;
Connected: Boolean;
Begin
Connected := False;
While (Not Terminated) And (Not Connected) Do
Begin
fThreadClients.Timeout := 5000;
With fThreadClients Do
res := NewSocket(Address, Port, nlTcp, {bind=}False, timeout, timeout, timeout, {retry=}0, client);
If res = nrOK Then
Begin
connection := nil;
If Not ConnectionCreate(client, {ip=}'', connection) Then
client.ShutdownAndClose({rdwr=}False)
Else
Begin
If connection <> nil Then
Begin
Connected := True;
While Not connection.IsClosed Do
SleepHiRes(1);
Log.Add.log(sllWarning, '%: connection closed - %', [self, connection], self);
Connected := False;
End;
End;
End
Else
Begin
Log.Add.log(sllWarning, '%: %:% connection failure (%)',
[self, fThreadClients.Address, fThreadClients.Port, ToText(res)^], self);
End;
End;
End;
Begin
Begin
Try
AsyncThreads := TFastClient.Create('127.0.0.1', '8080');
AsyncThreads.Connect(); // Will Never Return (Only on Fatel Error)
Finally
FreeAndNilSafe(AsyncThreads);
End;
End;
End.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment