MyHub.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. using Masuit.Tools;
  2. using Masuit.Tools.DateTimeExt;
  3. using Masuit.Tools.Hardware;
  4. using Masuit.Tools.Systems;
  5. using Microsoft.AspNetCore.SignalR;
  6. using System;
  7. using System.Collections.Concurrent;
  8. using System.Linq;
  9. using System.Threading;
  10. using System.Threading.Channels;
  11. using System.Threading.Tasks;
  12. namespace Masuit.MyBlogs.Core.Hubs
  13. {
  14. /// <summary>
  15. /// 性能计数器
  16. /// </summary>
  17. public class PerformanceCounter
  18. {
  19. /// <summary>
  20. /// 当前时间戳
  21. /// </summary>
  22. public double Time { get; set; }
  23. /// <summary>
  24. /// CPU当前负载
  25. /// </summary>
  26. public double CpuLoad { get; set; }
  27. /// <summary>
  28. /// CPU核心温度
  29. /// </summary>
  30. public double Temperature { get; set; }
  31. /// <summary>
  32. /// 内存使用率
  33. /// </summary>
  34. public double MemoryUsage { get; set; }
  35. /// <summary>
  36. /// 磁盘读
  37. /// </summary>
  38. public double DiskRead { get; set; }
  39. /// <summary>
  40. /// 磁盘写
  41. /// </summary>
  42. public double DiskWrite { get; set; }
  43. /// <summary>
  44. /// 网络上行
  45. /// </summary>
  46. public double Upload { get; set; }
  47. /// <summary>
  48. /// 网络下行
  49. /// </summary>
  50. public double Download { get; set; }
  51. }
  52. /// <summary>
  53. /// hub
  54. /// </summary>
  55. public class MyHub : Hub
  56. {
  57. /// <summary>
  58. /// 性能计数器缓存
  59. /// </summary>
  60. public static ConcurrentLimitedQueue<PerformanceCounter> PerformanceCounter { get; set; } = new ConcurrentLimitedQueue<PerformanceCounter>(5000);
  61. static MyHub()
  62. {
  63. Task.Run(() =>
  64. {
  65. int errorCount = 0;
  66. while (true)
  67. {
  68. try
  69. {
  70. PerformanceCounter.Enqueue(GetCurrentPerformanceCounter());
  71. }
  72. catch (Exception e)
  73. {
  74. if (errorCount > 20)
  75. {
  76. break;
  77. }
  78. Console.ForegroundColor = ConsoleColor.Red;
  79. Console.WriteLine(e.Message);
  80. Console.ForegroundColor = ConsoleColor.White;
  81. errorCount++;
  82. }
  83. Thread.Sleep(10000);
  84. }
  85. });
  86. }
  87. /// <summary>
  88. /// 初始化
  89. /// </summary>
  90. public static void Init()
  91. {
  92. }
  93. /// <summary>
  94. /// 当前连接客户端
  95. /// </summary>
  96. public static ConcurrentDictionary<string, bool> Connections { get; set; } = new ConcurrentDictionary<string, bool>();
  97. /// <summary>
  98. /// 连接事件
  99. /// </summary>
  100. /// <returns></returns>
  101. public override Task OnConnectedAsync()
  102. {
  103. Connections.TryAdd(Context.ConnectionId, false);
  104. return base.OnConnectedAsync();
  105. }
  106. /// <summary>
  107. /// 注销事件
  108. /// </summary>
  109. /// <param name="exception"></param>
  110. /// <returns></returns>
  111. public override Task OnDisconnectedAsync(Exception exception)
  112. {
  113. Connections.TryRemove(Context.ConnectionId, out _);
  114. return Task.CompletedTask;
  115. }
  116. /// <summary>
  117. /// 性能统计
  118. /// </summary>
  119. /// <param name="delay"></param>
  120. /// <param name="cancellationToken"></param>
  121. /// <returns></returns>
  122. public ChannelReader<object> Counter(int delay, CancellationToken cancellationToken)
  123. {
  124. var channel = Channel.CreateUnbounded<object>();
  125. _ = WriteItemsAsync(channel.Writer, delay, cancellationToken);
  126. return channel.Reader;
  127. }
  128. private async Task WriteItemsAsync(ChannelWriter<object> writer, int delay, CancellationToken cancellationToken)
  129. {
  130. if (Connections[Context.ConnectionId])
  131. {
  132. return;
  133. }
  134. byte errCount = 0;
  135. while (Connections.Any(s => s.Key.Equals(Context.ConnectionId)))
  136. {
  137. Connections[Context.ConnectionId] = true;
  138. try
  139. {
  140. cancellationToken.ThrowIfCancellationRequested();
  141. await writer.WriteAsync(GetCurrentPerformanceCounter(), cancellationToken);
  142. }
  143. catch (Exception e)
  144. {
  145. if (errCount > 20)
  146. {
  147. break;
  148. }
  149. Console.WriteLine("WebSocket出现错误:" + e.Message);
  150. errCount++;
  151. }
  152. if (cancellationToken.IsCancellationRequested)
  153. {
  154. break;
  155. }
  156. await Task.Delay(delay, cancellationToken);
  157. }
  158. writer.TryComplete();
  159. }
  160. private static PerformanceCounter GetCurrentPerformanceCounter()
  161. {
  162. double time = DateTime.Now.GetTotalMilliseconds(); // - 28800000;
  163. float load = SystemInfo.CpuLoad;
  164. double temperature = SystemInfo.GetCPUTemperature();
  165. double mem = (1 - SystemInfo.MemoryAvailable.To<double>() / SystemInfo.PhysicalMemory.To<double>()) * 100;
  166. var read = SystemInfo.GetDiskData(DiskData.Read) / 1024;
  167. var write = SystemInfo.GetDiskData(DiskData.Write) / 1024;
  168. var up = SystemInfo.GetNetData(NetData.Received) / 1024;
  169. var down = SystemInfo.GetNetData(NetData.Sent) / 1024;
  170. var counter = new PerformanceCounter()
  171. {
  172. Time = time,
  173. CpuLoad = load,
  174. Temperature = temperature,
  175. MemoryUsage = mem,
  176. DiskRead = read,
  177. DiskWrite = write,
  178. Download = down,
  179. Upload = up
  180. };
  181. return counter;
  182. }
  183. }
  184. }