In festen Intervallen räumt der Server dann auf, d.h. er durchläuft die Liste der verbundenen Clients und alle, die zu lange keinen Heartbeat mehr hatten, werden disconnected - zumindest in der Theorie.
Auf Anhieb kann ich keinen Fehler erkennen. Frage: funktioniert es unter Windows, aber unter Linux nicht? Oder auf beiden System nicht?
Als Alternative würde ich noch erwägen die Heartbeat-Prüfung nicht als Schleife über alle Context Objekte zu realisieren sondern innerhalb der OnExecute - Loop. Damit spart man sich das LockList, da man in OnExecute den zu prüfenden Context threadsicher untersuchen kann. (Auf diese Idee hat mich ein Beitrag von Remy Lebeau gebracht:
http://stackoverflow.com/a/1534800/80901).
In der OnExecute Loop kann man dann einfach eine (
Indy-)
Exception auslösen wenn der aktuelle Kontext zu lange kein Heartbeat-Signal mehr vom Client sah.
Ausgehend von diesem Codeschnipsel (
http://stackoverflow.com/a/14180366/80901):
Delphi-Quellcode:
procedure TMainForm.IdTCPServerExecute(AContext: TIdContext);
var
...
begin
...
if AContext.Connection.IOHandler.InputBufferIsEmpty then
begin
if not AContext.Connection.IOHandler.CheckForDataOnSource(100) then
begin
AContext.Connection.IOHandler.CheckForDisconnect;
Exit;
end;
end;
TCliContext(AContext).ProccessMsg;
TCliContext(AContext).Activity_time := Now();
end;
... würde man nach dem CheckForDataOnSource auch die Activity_time prüfen und - falls sie "zu alt" ist - eine TIdException auslösen anstatt die Methode mit Exit zu verlassen. Durch die
Exception erfährt der Server, dass er den Context freigeben und die Verbindung trennen soll.