-
-
Save Coldzer0/8c98a02721979abe116c9089791f55e4 to your computer and use it in GitHub Desktop.
mORMot2 Async Client Demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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