And when we print: (Myconnections array fixed size is 1..200)
length(MyConnections)/ServerClientsCount
we got 200/200... for some time...then slowly the second number slowly increases (average ~1 per hour), so it means that there are some connections/threads in the server that "we are not handling" properly.
Most likely, you are blocking the server from processing the disconnects so it can clean up the contexts properly. For instance, if you were swallowing Indy exceptions and not letting the server process them. Can't be sure, since you have not shown enough of your server code to know what it is actually doing, particularly is
OnExecute logic.
It is pretty weird because the onConnect procedure have a call to disconnect the new connection if it was not added to myconnections:
That logic looks fine, provided it is adequately protected with
try..finally, and you are not going out of bounds of your
myconnections array.
Could you give us an idea how we could access the Server contexts lists?
You already know how, since you are accessing it in
ServerClientsCount().
LockList() returns a pointer to a
TList which holds
TIdContext object pointers. You are merely reading the
Count of that list, but you can also iterate through it, too.
With it, we could compare with the Myconnection contexts
I doubt that will help. Since you are adding contexts to your array in the
OnConnect event, and removing contexts from your array in the
OnDisconnect event, you are likely to find that the two lists are always in sync containing the same
TIdContext objects (provided you are managing your array correctly).
and get what are the not tracked one to close those connections.
If you find a
TIdContext in your array that the server is not tracking in its
Contexts list, then that object is gone, you can't close it, or do anything else with it. You have a dangling pointer.
If you find a
TIdContext in the server's
Contexts list that your array is not tracking, then your tracking logic is faulty. Except in the very small window of opportunity when a client connects/disconnects where:
- a new client has been added to the
Contexts list but has not been added to your array yet.
- an existing client has been removed from your array but has not been removed from the
Contexts list yet.
This is another reason why I do not recommend using your own array at all. You are basically just mirroring the
Contexts list redundantly.
if length(MyConnections) <> ServerClientsCount then
You do realize that condition will always be true except when your server is running at max capacity (200 clients), don't you?
begin
for counter := 0 to ServerClientsCount-1 do
if IdTCPServer1.Contexts[counter] doNotExistsInMyConnections then
IdTCPServer1.Contexts[counter].Connection.Disconnect;
end;
Make sure this loop is inside a
LockList/
UnlockList pair, or else the
ServerClientsCount can change value if clients connect/disconnect while you are looping.
Also, that scan is only checking for
TIdContext objects that exist in the
Contexts list but not in the array. It is not checking for
TIdContext objects that exist in the array but not in the
Contexts list.
Also, when disconnecting a client from outside of its own events, it may be safer to use
TIdContext(IdTCPServer1.Contexts[counter]).Binding.CloseSocket() instead of
TIdContext(IdTCPServer1.Contexts[counter]).Connection.Disconnect().