delphi - 如何防止 TIdTcpServer 泛滥和连接卡住
问题描述
我的 TIdTcpServer 上的洪水出现了一些问题,并且阻止了客户在 TIdTcpServer 上连接,其他问题是 TIdTcpServer 上的连接卡住了,所以我们需要在几个小时后重新启动服务器应用程序才能恢复工作,如果不是客户端不连接。
这是我在服务器端的代码:
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;
我只使用 OnExecute 方法,这些函数是谁:
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);
这是 TLog 函数:
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;
我还在 TIdTcpServer 上使用了 IdSchedulerOfThreadPool1 实例。
任何想法?
解决方案
推荐阅读
- containers - 使用 aa-genprof 为容器应用程序自动生成配置文件
- node.js - 在某些请求中更改测试库 IP?
- sql - 使用小数(10,1)计算时间时的结果差异
- julia - 从二进制文件中读取数组:“读取文件结尾”错误
- javascript - 移动设备上的 Google Oauth 需要 client_secret 但生成的客户端不提供
- rholang - Rholang 与 AND 和 RevAddress 匹配
- r - LMEST 解码问题
- flutter - Flutter just_audio 包,无法通过 Note 9 扬声器获得声音(适用于其他设备)
- jenkins - 在 Jenkins 中失败一个阶段但保持构建结果为成功
- python - 表模型更新时 Qtableview 不更新