【发布时间】:2013-05-16 11:16:53
【问题描述】:
我很难自己解决这个问题,因此在这里问。 我有一个在远程机器上安装客户端的应用程序 客户端通过套接字返回报告。
我正在尝试创建一个保持计时器。这意味着客户端将每 1 分钟向服务器发送一个 hello 消息。如果服务器在保持计时器内没有收到来自客户端的 hello 数据包,则客户端被删除。 我可以和一个客户一起做... 但对于多个我无法弄清楚。 我正在考虑为连接到服务器的每个新客户端创建一个线程。然后在该线程内启动一个保持计时器。但是我如何通过线程将客户端与另一个客户端区分开来,以及如果从客户端收到一个 hello 数据包,我如何重置保持计时器。
我想为每个 hello 数据包创建一个新线程并停止旧线程。 但我不知道这会占用多少 CPU 资源
如果你不明白我的问题,请说出来,我会尽力解释你不明白的。
哪种解决方案更好? 解决方案 A) 每次问候数据包到达时启动一个新线程并停止旧线程? (每 40 秒)- 来自 100 个客户
解决方案 B) 在此处插入更好、更具可扩展性的解决方案。
解决方案 C) 我可以访问我动态创建的线程内的计时器吗? - 我在所有动态创建的线程上都有唯一的线程名。
public void _clientholdtimer()
{
holdtimer = new Timer();
holdtimer.Interval = SECtoMS(Settings.Default.Hold);
holdtimer.Elapsed += holdtimer_Elapsed;
}
当我从客户端收到与线程同名的 hello 数据包时重置它?
解决方案 D) 将计时器存储在字典中 公共词典 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 秒,我会考虑让客户端断开连接。
【问题讨论】:
-
您可以发布您已有的代码吗?我找不到任何会阻止您设计解决方案的具体问题。也许更容易看到你做错了什么并指出来。
-
嗯,就是这样,我无法解决这个问题。我没有无效的代码。我想不出这样做的最佳方法
-
你能让服务器成为一个 ASP.NET 应用程序并让客户端通过 HTTP 调用服务器吗?这样一来,基础架构就可以管理连接,所有这些问题都消失了。
-
我不能这样做。套接字按应有的方式工作并且客户端受到管理,保持计时器是服务器端而不是客户端 - 当我在服务器上收到一条消息时,客户端发送一个带有 client.ID 的字符串“hello#”,我将 case 切换为“hello#”
标签: c# multithreading timer system.reactive