Reputation: 12423
I'm writing a simple C# tcp message-server that needs to respond to the fact that a connected client has been silent the last TimeSpan timeout
. In other words
timeout
time passes without client A sending anything.SendPing
) to A.pingTimeout
time after ping was sent to A, connection to A is dropped, and the client is removed.Simple story short. If no word has been heard from client[n]
within timeout
, send ping. If ping is replied to, simply update client[n].LastReceivedTime
, however, if client[n]
fails to respond within pingTimeout
, drop the connection.
As far as I understand, this must be done with some kind of scheduler, cause simply making a loop which says something like this
while(true) {
foreach(var c in clients) {
if(DateTime.Now.Subtract(c.LastReceivedTime) >= timeout && !c.WaitingPing)
c.SendPing();
else if(DateTime.Now.Subtract(c.LastReceivedTime) >= timeout + pingTimeout && c.WaitingPing)
c.Drop();
}
}
would simply fry the CPU and would be no good at all. Is there a good simple algorithm/class for handling cases like this that can easily be implemented in C#? And it needs to support 100-500 clients at once (as a minimum, it is only positive if it can handle more).
Upvotes: 3
Views: 294
Reputation: 17719
Your solution would be Ok I think if you use a dedicated thread and put a Thread.Sleep(1000)
in there so you dont as you say fry the CPU. Avoid blocking calls on this thread eg make sure your calls to SendPing
and Drop
are asynchronous so this thread only does one thing.
The other solution is to use a System.Timers.Timer
per client connection which has an interval equal to your ping timer. I'm using this method and have tested this with 500 clients with no issues. (20 sec interval). If your interval is much shorter I would not recommend this and look at other solutions using a single thread to check (like your solution)
Upvotes: 2