MyHub.cs 5.9 KB

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