Habe hierzu nochmal eine Frage:
Ich habe jetzt den Heartbeat eingebaut, der Client schickt in einem Intervall die Heartbeats und der Server antwortet.
In der ContextClass des Servers werden die MacAdresse und der Zeitpunkt des letzten Heartbeats des Clients gespeichert. 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.
Der Client erkennt inzwischen korrekt, ob er keine Verbindung mehr hat, der Server vom Prinzip her auch.
Delphi-Quellcode:
procedure TMyServer.HeartbeatCheck();
var
ContextList:TList;
Context:TIdContext;
i:integer;
begin
ContextList := TCPServer.Contexts.LockList;
try
for i := 0 to ContextList.Count-1 do
begin
Context := TIdContext(ContextList.Items[i]);
if (IncSecond(TClientIdentifier(Context).Heartbeat, CLIENTTIMEOUT) < Now) and (TClientIdentifier(Context).Heartbeat <> 0) then
begin
Log('Client '+TClientIdentifier(Context).Mac+' timed out', ltE);
TIdContext(ContextList.items[i]).Connection.IOHandler.close;
TIdContext(ContextList.items[i]).Connection.Disconnect();
end;
end;
finally
TCPServer.Contexts.UnlockList;
end;
end;
Wenn ein Client die Verbindung verliert, wird das entsprechend geloggt, doch in JEDEM Durchlauf wird er erneut als timed out erkannt - dabei sollte er ja eigentlich aus der Liste gelöscht werden?!
Und auch wenn der Client die Verbindung wieder aufnimmt und Heartbeats schickt, wird er dennoch wieder getrennt.
Im OnDisconnect des Servers wird eigentlich ebenfalls geloggt, dass ein bestimmter Client die Verbindung getrennt hat - dies wird in der Heartbeat Methode aber offenbar gar nicht ausgelöst. Vielleicht ist es ja nur ein ganz einfacher blöder Fehler
Viele Grüße!