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
|
{
|
/// <summary>
|
/// Client监控线程
|
/// </summary>
|
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<Client> 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);//
|
}
|
|
/// <summary>
|
/// 客户端心跳上送
|
/// </summary>
|
/// <param name="client"></param>
|
/// <param name="clientIP"></param>
|
/// <returns></returns>
|
public async Task<ApiAction> 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
|
}
|
}
|