using Rhea.Common;
using Rhea.Common.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Tiger.IBusiness;
namespace Tiger.Business
{
///
/// Client监控线程
///
public class ClientMonitor : IClientMonitor
{
#region Variables
private WhileThread ClientMonitorThread;
#endregion
#region Propertys
public string Id { get; set; } = Guid.NewGuid().ToString("N");
public string Tag { get; set; } = "ClientMonitor";
public string Name { get; set; } = "ClientMonitor";
public bool IsRunning { get; set; }
public List OnlineClients { get; set; } = new();
#endregion
#region Functions
public void Start()
{
try
{
ClientMonitorThread = new(ClientMonitoring);
ClientMonitorThread.Start();
Logger.Default.Info("Start Client Monitoring Thread");
}
catch (System.Exception ex)
{
Logger.Default.Fatal(ex, "Start Client Monitoring Thread Exception");
}
}
public void Stop()
{
try
{
ClientMonitorThread?.Stop();
Logger.Console.Info("Stop Client Monitoring Thread");
}
catch (System.Exception ex)
{
Logger.Console.Fatal(ex, "Stop Client Monitoring Thread Exception");
}
}
private void ClientMonitoring()
{
try
{
var clients = OnlineClients.Where(q => (DateTime.Now - q.LastAccessTime).TotalMinutes > ApiConfig.Client_TimeoutMinutes);
foreach (var client in clients)
{
Logger.Console.Info($"Client[{client.IP}] timeout for {(DateTime.Now - client.LastAccessTime).TotalMinutes} minutes.(id: {client.Id})");
}
OnlineClients.RemoveAll(q => !q.IsLive || (DateTime.Now - q.LastAccessTime).TotalMinutes > ApiConfig.Client_TimeoutMinutes);
}
catch (System.Exception ex)
{
Logger.Console.Fatal(ex, "客户端监控线程异常,重置所有客户端");
OnlineClients.Clear();
}
//休眠10分钟
Thread.Sleep(5 * 60 * 1000);//
}
///
/// 客户端心跳上送
///
///
///
///
public async Task Heartbeat(Client client, string clientIP)
{
var action = new ApiAction();
try
{
if (!OnlineClients.Any(q => q.Id == client.Id))
{
OnlineClients.Add(client);
Logger.Console.Info($"Client[{clientIP}] online.(id: {client.Id})");
}
var online = OnlineClients.FirstOrDefault(q => q.Id == client.Id);
online.IsLive = true;
online.IP = clientIP.Split(':')[0].IsNullOrEmpty() ? clientIP : clientIP.Split(':')[0];
online.LastAccessTime = DateTime.Now;
if (client.HeartbeatRate <= 0)
{
online.IsLive = false;
Logger.Console.Info($"Client[{clientIP}] offline.(id: {online.Id})");
}
action.Message = online.IP;
action.Data = online;
}
catch (System.Exception ex)
{
action.CatchExceptionWithLog(ex, "客户端心跳上送异常");
}
return action;
}
#endregion
}
}