我有三个问题:
是否可以通过多个连接销毁IdTCPServer? 我试图测试我的应用程序,当我有几个连接 - 它工作得非常好(甚至几天),但有时连接数增加应用程序会导致访问违规。我写的应用程序模拟了50个客户端不断发送数据(只有睡眠(200))。在这种情况下,IdTCPServer会给出异常吗? 我的应用程序使用onExecute事件和modyfies数据库表从客户端重新发送信息 TidNotify和TIdSync类。我相信它保护了十字架连接线程? 向客户发送信息是由TTimer完成的(现在,我将其更改为其他线程)。 我是否在这种情况下使用特殊保护或类似的东西就足够了:
type
PClient = ^TClient;
TClient = record
Activity_time:TDateTime;
AContext: TIdContext;
end;
...
list := server.Contexts.LockList;
try
for i := 0 to list.Count - 1 do
with TIdContext(list[i]) do
begin
if SecondsBetween(now(), PClient(data)^.activity_time) > 6 then
begin
Connection.IOHandler.Close;
Continue;
end;
try
Connection.IOHandler.writeln('E:');
Except
Connection.IOHandler.Close;
end;
end;
finally
server.Contexts.UnlockList;
end;
2.当服务器忙时,这是一种拒绝连接的简单方法(我认为我的数据库并不复杂(100行,只有一行被一个连接修改)但是这里可能是一种保持服务器稳定性的方法?
3.我知道这个问题重复了很多次但是我没有找到满意的答案:如何保护应用程序以避免消息异常:“连接正常关闭”和“通过对等方重置连接”?
感谢您提供所有建议
答案 0 :(得分:3)
是否可以通过多次连接销毁IdTCPServer?
你问的是错误的问题,因为你实际上并没有破坏TIdTCPServer
本身,你只是从外部线程关闭空闲连接。这种逻辑可以(并且应该)在OnExecute
事件内处理,而不是最安全的访问连接,例如:
type
PClient = ^TClient;
TClient = record
Activity_time: TDateTime;
Heartbeat_time: TDateTime;
AContext: TIdContext;
end;
procedure TForm1.serverConnect(AContext: TIdContext);
var
Client: PClient;
begin
New(Client);
Client^.Activity_time := Now();
Client^.Heartbeat_time := Client^.Activity_time;
AContext.Data := TObject(Client);
end;
procedure TForm1.serverDisconnect(AContext: TIdContext);
var
Client: PClient;
begin
Client := PClient(AContext.Data);
AContext.Data := nil;
if Client <> nil then Dispose(Client);
end;
procedure TForm1.serverExecute(AContext: TIdContext);
var
Client: PClient;
dtNow: TDateTime;
begin
Client := PClient(AContext.Data);
dtNow := Now();
if SecondsBetween(dtNow, Client^.Activity_time) > 6 then
begin
AContext.Connection.Disconnect;
Exit;
end;
if SecondsBetween(dtNow, Client^.Heartbeat_time) > 2 then
begin
AContext.Connection.IOHandler.WriteLn('E:');
Client^.Heartbeat_time := dtNow;
end;
if AContext.Connection.IOHandler.InputBufferIsEmpty then
begin
if not AContext.Connection.IOHandler.CheckForDataOnSource(100) then
Exit;
end;
// process incoming data as needed ...
Client^.Activity_time := Now();
end;
当服务器忙时,这是一种拒绝连接的简单方法(我认为我的数据库并不复杂(100行,只有一行由一个连接修改)但是这可能是保持服务器稳定性的一种方法吗? / p>
当前体系结构不允许拒绝接受连接。您可以让服务器正常接受连接,然后在需要时关闭接受的连接。您可以在OnConnect
事件中执行此操作,也可以将服务器的MaxConnection
属性设置为低非零数字,以允许服务器为您自动断开新连接,而不会浪费资源创建新{ {1}}对象和线程。
另一种选择是在服务器繁忙时调用服务器的TIdContext
方法,以便新连接不再能够到达服务器,然后在准备好接受新服务时调用服务器的StopListening()
方法客户了。已经连接的现有客户不应该受到影响,尽管我自己还没有真正尝试过。
我知道这个问题重复了很多次但是我没有找到满意的答案:如何保护应用程序以避免消息异常:“连接正常关闭”和“由同行重置连接”?
你不应该避免它们。让他们发生,他们是正常的错误。如果它们发生在服务器的事件内部,只需让服务器正常处理它们。这就是设计使用StartListening()
的方式。如果它们发生在服务器事件之外,例如在您的计时器中,那么只需将套接字操作包装在TIdTCServer
块中并继续。