服务端的TigerApi 框架,基于.NET6 2024 版本
Ben Lin
2025-02-19 e8aef02a3b8a6b6c5f0b13798f318aa7dc56e13f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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
    }
}