我很难自己解决这个问题,因此在这里问。我有一个在远程机器上安装客户端的应用程序,客户端通过套接字返回报告。
我试图创建一个保持计时器。这意味着客户端将每 1 分钟向服务器发送一个 hello 消息。如果服务器在保持计时器内没有收到来自客户端的 hello 数据包,则客户端被删除。我可以对一个客户做得很好......但对于多个我无法弄清楚。我正在考虑为连接到服务器的每个新客户端创建一个线程。然后在该线程内启动一个保持计时器..但是我如何使用线程将客户端与另一个客户端区分开来,以及如果从客户端收到一个问候数据包,我如何重置保持计时器。
我想为每个 hello 数据包创建一个新线程并停止旧线程。但我不知道这会占用多少 CPU
如果您不理解我的问题,请这样说,并尝试解释您不理解的任何内容。
哪个解决方案更好?解决方案 A) 每次收到 hello 数据包时启动一个新线程并停止旧线程?(每 40 秒)- 来自 100 个客户
解决方案 B) 在此处插入更好、更具可扩展性的解决方案。
解决方案 C)我可以访问我动态创建的线程内的计时器吗?- 我在所有动态创建的线程上都有唯一的线程名。
public void _clientholdtimer()
{
holdtimer = new Timer();
holdtimer.Interval = SECtoMS(Settings.Default.Hold);
holdtimer.Elapsed += holdtimer_Elapsed;
}
并在我从客户端收到与线程同名的 hello 数据包时重置它?
解决方案 D) 将计时器存储在字典中 public Dictionary timersDict = new Dictionary(); 并且循环在收到的 hello 数据包的 dict 中找到引用重置该计时器。?
foreach(var item in timersDict)
{
if(item.Key == stripip(client.RemoteEndPoint.ToString()))
TimerReset(item.Value);
}
解决方案
设置远程主机应用程序,每 3 秒向服务器发送一条“hello”消息。在服务器上创建一个计时器,每 1 秒触发一次经过的事件。设置一个静态值来保存一个 int,它决定了在我认为远程机器死机之前多久,我选择了 9 秒。
当服务器接收到 hello 消息时,它将时间戳与客户端的 IP 地址一起存储在一个列表中。
在 timer_elapsed 事件上
void holdtimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try
{
if (server.Clients.GetAllItems().Count != 0)
{
foreach (IScsServerClient _client in server.Clients.GetAllItems())
{
string ipaddr = stripip(_client.RemoteEndPoint.ToString());
bool containsentry = _clientlist.Any(item => item.ipadress == ipaddr);
if (containsentry)
{
foreach (Scsserverclient entry in _clientlist.Where(entry => entry.ipadress == ipaddr))
{
if ((DateTime.Now - TimeSpan.FromSeconds(Settings.Default.Hold)) > entry.lasthello &&
entry.isConnect != "Disconnected")
{
entry.client.Disconnect();
}
}
}
}
}
}
catch (Exception ex)
{
}
}
基本上我浏览了一个已连接客户端的列表,如果最后收到的 hello 消息超过 9 秒,我会考虑让客户端断开连接。