unit DTS_Server;
interface
uses
Windows, Classes, IdTCPServer, SysUtils, DTS_Command, DTS_Utils,
IdSocketHandle, SyncObjs, Contnrs;
Type
TServerOnRead =
Procedure(AThread: TIdPeerThread; Data : TCommandHandling)
of object;
TServerOnEvent =
Procedure(AThread: TIdPeerThread)
of object;
TClientData =
class(TObject)
private
fDNS :
String;
{ Hostname }
fConnected,
{ Time of connect }
fLastAction : TDateTime;
{ Time of last transaction }
fThread : Pointer;
{ Pointer to thread }
public
Property DNS :
String read fDNS
write FDNS;
Property Connected : TDateTime
read fConnected
write fConnected;
Property LastAction : TDateTime
read fLastAction
write fLastAction;
Property Thread : Pointer
read fThread
write fThread;
end;
TDTSServer =
class(TThread)
private
fPort : Integer;
fClientList : TobjectList;
fServer : TIdTCPServer;
fOnRead : TServerOnRead;
fOnDisconnect : TServerOnEvent;
fBindIP :
String;
Procedure OnExecute(AThread: TIdPeerThread);
Procedure OnConnect(AThread: TIdPeerThread);
Procedure OnDisconnect(AThread: TIdPeerThread);
public
Constructor Create(Port : integer; BindIP :
String = '
127.0.0.1');
Destructor Destroy;
override;
Procedure Broadcast(Data : TCommandHandling);
Property OnClientReadData : TServerOnRead
read fOnRead
write fOnRead;
Property OnClientDisconnect : TServerOnEvent
read fOnDisconnect
write fOnDisconnect;
protected
Procedure Execute;
override;
Procedure DoTerminate;
override;
end;
implementation
{ TDTSServer }
procedure TDTSServer.Broadcast(Data: TCommandHandling);
var
i : integer;
RecClient : TClientData;
RecThread : TIdPeerThread;
begin
try
for i := 0
to fClientList.Count-1
do // iterate through client-list
begin
RecClient := TClientData(fClientList.Items[i]);
// get client-object
RecThread := RecClient.Thread;
// get client-thread out of it
RecThread.Connection.WriteLn(Data.SendFrames);
// send the stuff
end;
finally
FreeAndNil(Data);
end;
end;
constructor TDTSServer.Create(Port: integer; BindIP :
String = '
127.0.0.1');
begin
inherited Create(false);
fPort := Port;
fBindIP := BindIP;
end;
destructor TDTSServer.Destroy;
begin
self.Terminate;
self.WaitFor;
inherited;
end;
procedure TDTSServer.DoTerminate;
begin
inherited;
end;
procedure TDTSServer.Execute;
var
MSG : TMsg;
Binding : TIdSocketHandle;
begin
inherited;
fClientList := TObjectList.Create;
fServer := TIdTCPServer.Create(
nil);
// fServer.TerminateWaitTime := 3000;
fServer.Bindings.Clear;
Binding := fServer.Bindings.Add;
Binding.IP := fBindIP;
Binding.Port := fPort;
fServer.OnExecute := OnExecute;
fServer.OnConnect := OnConnect;
fServer.OnDisconnect := OnDisconnect;
fServer.Active := true;
while not Terminated
do begin
sleep(100);
end;
// while (GetMessage(msg, 0, 0, 0) and not Terminated) do
// DispatchMessage(msg);
fServer.Active := false;
FreeAndNil(fServer);
FreeAndNil(fClientList);
end;
procedure TDTSServer.OnConnect(AThread: TIdPeerThread);
var
Data : TClientData;
begin
Data := TClientData.Create;
Data.DNS := AThread.Connection.LocalName;
Data.Connected := Now;
Data.LastAction := Now;
Data.Thread := AThread;
AThread.Data := TClientData(Data);
fClientList.Add(Data);
end;
procedure TDTSServer.OnDisconnect(AThread: TIdPeerThread);
var
Data : TClientData;
begin
if(Assigned(fOnDisconnect))
then
fOnDisconnect(AThread);
Data := TClientData(AThread.Data);
fClientList.Remove(Data);
AThread.Data :=
nil;
end;
procedure TDTSServer.OnExecute(AThread: TIdPeerThread);
var
msg :
string;
cmd : TCommandHandling;
begin
AThread.Connection.ReadTimeout := 1000;
try
msg := AThread.Connection.ReadLn;
except
exit;
end;
cmd := TCommandHandling.Create(CMDPong);
try
cmd.SetFrames(msg);
if cmd.GetCmd = CMDPing
then
begin
cmd.SetCommand(CMDPong);
AThread.Connection.WriteLn(cmd.SendFrames);
end else begin
if Assigned(fOnRead)
then
//Weiter an die eigentliche Command behandlung.
fOnRead(AThread, cmd);
end;
finally
FreeAndNil(cmd);
end;
end;
end.