i'm having some problems with flood on my TIdTcpServer and that are blocking the customers to connect at TIdTcpServer, Other problem is stuck connections at TIdTcpServer so we need restart the server application after some hours to back work, if not the clients don't connect.
This is my code at server side:
type
TCommand = (
CustomerConnect,
CustomerDisconnect,
CustomerNotification);
type
TClient = record
CustomerName : String[40];
Notification : String[40];
end;
const
szClient = SizeOf(TClient);
type
TProtocol = record
Command: TCommand;
Sender: TClient;
DataSize: Integer;
end;
const
szProtocol = SizeOf(TProtocol);
type
TClientContext = class(TIdServerContext)
private
FCriticalSection : TCriticalSection;
FClient : TClient;
public
Queue : TIdThreadSafeStringList;
constructor Create(AConnection: TIdTCPConnection; AYarn: TIdYarn; AList: TIdContextThreadList = nil); override;
destructor Destroy; override;
public
procedure Lock;
procedure Unlock;
public
property Client: TClient read FClient write FClient;
end;
i only use OnExecute method, who is these functions:
type
PTBytes = ^TBytes;
PTIdBytes = ^TIdBytes;
var
LBuffer : TIdBytes;
LProtocol : TProtocol;
FTempBuffer : TIdBytes;
ToSend : TBytes;
Protocol : TProtocol;
Con : TClientContext;
Queue : TStringList;
List : TStringList;
x : Integer;
begin
Con := TClientContext(AContext);
List := nil;
try
Queue := Con.Queue.Lock;
try
if Queue.Count > 0 then
begin
List := TStringList.Create;
List.Assign(Queue);
Queue.Clear;
end;
finally
Con.Queue.Unlock;
end;
if List <> nil then
begin
Con.Lock;
for x := 0 to List.Count-1 do
begin
if List.Strings[x] = 'Notification' then
begin
InitProtocol(Protocol);
Protocol.Command := CustomerNotification;
Protocol.Sender.Notification := 'Custom Notification';
ToSend := ProtocolToBytes(Protocol);
Con.Connection.IOHandler.Write(PTIdBytes(@ToSend)^);
ClearBuffer(ToSend);
end;
end;
Con.Unlock;
end;
finally
List.Free;
end;
// Protocol
AContext.Connection.IOHandler.ReadBytes(LBuffer, szProtocol, False);
LProtocol := BytesToProtocol(PTBytes(@LBuffer)^);
case LProtocol.Command of
CustomerConnect: begin
TLog.AddMsg('Connect');
end;
CustomerDisconnect: begin
TLog.AddMsg('Disconnect');
end;
end;
ClearBufferId(LBuffer);
IndySleep(10);
And here is the TLog function:
constructor TLog.Create(const AMsg: String);
begin
FMsg := AMsg;
inherited Create;
end;
procedure TLog.DoSynchronize;
var
LogName: String;
ToFile: TextFile;
begin
try
LogName := ExtractFilePath(ParamStr(0))+'Logs\LogFile.txt';
AssignFile(ToFile, LogName);
if FileExists(LogName) then Append(ToFile) else ReWrite(ToFile);
try
WriteLn(ToFile, FMsg);
finally
CloseFile(ToFile);
end;
except
end;
Form1.Memo1.Lines.Add(FMsg);
end;
class procedure TLog.AddMsg(const AMsg: String);
begin
with Create(AMsg) do
try
Synchronize;
finally
Free;
end;
end;
I also use a IdSchedulerOfThreadPool1 instance on TIdTcpServer.
Any idea?