137 lines
3.9 KiB
ObjectPascal
137 lines
3.9 KiB
ObjectPascal
unit tcpserver;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, tcpthreadhelper, extTypes;
|
|
type
|
|
{ TServerThread }
|
|
|
|
TServerThread=class(TConnectionThread)
|
|
class function Role: string; override;
|
|
procedure ProcessMessage(const mode: byte; const Code:DWORD; const Param:QWord; const ACommand: string;const Values: TStrings; const intData: TParamArray; const Data: TStream); override;
|
|
end;
|
|
|
|
{ TServerMainThread }
|
|
TCommandReceived=function(Sender: TMainThread;
|
|
const CommandID:DWORD; const Param:QWord; const ACommand: string; const Fields: TStrings; const iParams: TParamArray; const Data: TStream;
|
|
out Code: DWORD; out RetValue: QWord; out Answer: string; out rValues: TStrings; out iValues: TParamArray; out ByteData: TStream ): boolean of object;
|
|
|
|
TServerMainThread=class(TMainThread)
|
|
private
|
|
fOnReceive: TCommandReceived;
|
|
fOnIdle: TNotifyEvent;
|
|
function processReceive(const CommandID:DWORD; const Param:QWord; const ACommand: string; const Fields: TStrings; const iParams: TParamArray; const Data: TStream;
|
|
out Code: DWORD; out RetValue: QWord; out Answer: string; out rValues: TStrings; out iValues: TParamArray; out ByteData: TStream): boolean;
|
|
public
|
|
property OnIdle: TNotifyEvent read fOnIdle write fOnIdle;
|
|
procedure execute; override;
|
|
constructor Create( ALogger: TLogger; APort: integer; OnReceive:TCommandReceived);
|
|
end;
|
|
|
|
implementation
|
|
{ TServerMainThread }
|
|
|
|
function TServerMainThread.processReceive(const CommandID: DWORD;
|
|
const Param: QWord; const ACommand: string; const Fields: TStrings;
|
|
const iParams: TParamArray; const Data: TStream; out Code: DWORD; out
|
|
RetValue: QWord; out Answer: string; out rValues: TStrings; out
|
|
iValues: TParamArray; out ByteData: TStream): boolean;
|
|
begin
|
|
log(mtDebug,self,'ProcessReceive '+ACommand);
|
|
if assigned(fOnReceive) then
|
|
result := fOnReceive(self,CommandID,Param,ACommand,Fields,IParams,Data,Code,RetValue,Answer,rValues,iValues,ByteData)
|
|
else
|
|
begin
|
|
log(mtWarning,self,'Processor not assigned');
|
|
result := false;
|
|
Code := ErrorProcessor;
|
|
RetValue := 0;
|
|
Answer := 'Server error';
|
|
rValues := nil;
|
|
setLength(iValues,0);
|
|
ByteData := nil;
|
|
end;
|
|
end;
|
|
|
|
procedure TServerMainThread.execute;
|
|
var
|
|
n: integer;
|
|
begin
|
|
doStart;
|
|
log(mtExtra,self,'start main thread');
|
|
Connect.Listen(Port);
|
|
n := 0;
|
|
while not terminated and not Complete do
|
|
begin
|
|
try
|
|
Connect.CallAction;
|
|
|
|
except on e: Exception do
|
|
log(mtError,e, '!!ERROR '+e.message);
|
|
end;
|
|
sleep(10);
|
|
inc(n);
|
|
if n>100 then
|
|
begin
|
|
if Assigned(fOnIdle) then fOnIdle(self);
|
|
n :=0;
|
|
end;
|
|
inc(n);
|
|
end;
|
|
TerminateClients;
|
|
end;
|
|
|
|
constructor TServerMainThread.Create(ALogger: TLogger; APort: integer;
|
|
OnReceive: TCommandReceived);
|
|
begin
|
|
inherited Create(TServerThread,ALogger,APort);
|
|
fOnReceive := OnReceive;
|
|
Connect.OnAccept:=@Accept;
|
|
//FreeOnTerminate:=true;
|
|
end;
|
|
{ TServerThread }
|
|
|
|
class function TServerThread.Role: string;
|
|
begin
|
|
result := 'SERVER';
|
|
end;
|
|
|
|
procedure TServerThread.ProcessMessage(const mode: byte; const Code: DWORD;
|
|
const Param: QWord; const ACommand: string; const Values: TStrings;
|
|
const intData: TParamArray; const Data: TStream);
|
|
var
|
|
s: string;
|
|
Vals: TStrings;
|
|
B: TStream;
|
|
res: DWORD;
|
|
rVal: QWord;
|
|
iVals: TParamArray;
|
|
ok: boolean;
|
|
begin
|
|
log(mtDebug, format('ProcessMessage(%d) Param=%x, Command %s ',[code,Param,ACommand]));
|
|
try
|
|
ok := (Owner as TServerMainThread).ProcessReceive(Code,Param,ACommand,Values,IntData,Data,res,rVal,s,Vals,iVals,B);
|
|
try
|
|
if OK then
|
|
SendMessage(cmdAnswer,res,rVal, s,Vals,iVals,B)
|
|
else
|
|
SendMessage(cmdError,res,rVal,s,Vals);
|
|
finally
|
|
if Assigned(Vals) then Vals.Free;
|
|
if Assigned(B) then B.Free;
|
|
end;
|
|
|
|
except on e:Exception do
|
|
begin
|
|
log(mtError,'!!ERROR ProcessMessage '+e.message);
|
|
raise;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end.
|
|
|