QMonClient.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. using System.ComponentModel.DataAnnotations;
  2. using System.IO.Abstractions;
  3. using System.Net;
  4. using System.Net.Sockets;
  5. using System.Reflection;
  6. using System.Text;
  7. using qmonlib.Attributes;
  8. using Quadarax.Foundation.Core.Logging;
  9. using Quadarax.Foundation.Core.Reflection.Extensions;
  10. namespace qmonlib
  11. {
  12. public class QMonClient : QMonHostBase<QMonClientConfiuration>
  13. {
  14. #region *** Properties ***
  15. protected override Uri UriGeneral => Configuration.TargetUriGeneral;
  16. protected override Uri UriData => Configuration.TargetUriData;
  17. protected override TimeSpan IntervalGeneral => Configuration.EmitGeneralInterval;
  18. protected override TimeSpan? IntervalData => Configuration.EmitDataInterval;
  19. public string InstanceIdentifier { get; }
  20. #endregion
  21. #region *** Fields ***
  22. private IDictionary<string, MonItemGeneral> _generalCache = new Dictionary<string, MonItemGeneral>();
  23. #endregion
  24. #region *** Constructors ***
  25. public QMonClient(string instanceIdentifier, QMonClientConfiuration configuration, ILogger? externalLogger) : base(configuration, externalLogger)
  26. {
  27. InstanceIdentifier = instanceIdentifier ?? throw new ArgumentNullException(nameof(instanceIdentifier));
  28. ScanAssemblies();
  29. }
  30. private void ScanAssemblies()
  31. {
  32. var assemblies = AppDomain.CurrentDomain.GetAssemblies();
  33. foreach (var assembly in assemblies)
  34. {
  35. var types = assembly.GetTypesWithAttribute<MonitoredClassAttribute>(true);
  36. foreach (var type in types)
  37. {
  38. var monItemGeneral = new MonItemGeneral
  39. {
  40. Caption = type.GetCustomAttribute<MonitoredClassAttribute>()?.Caption ?? type.Name,
  41. Description = type.GetCustomAttribute<MonitoredClassAttribute>()?.Description ?? string.Empty,
  42. ViewType = MonItemGeneral.MonViewType.Item
  43. };
  44. var properties = type.GetPropertiesWithAttribute<MonitoredPropertyAttribute>(true);
  45. var keys = new List<Tuple<string,int>>();
  46. foreach (var property in properties)
  47. {
  48. var itemDescriptor = new MonItemGeneral.ItemDescriptor
  49. {
  50. Name = property.Name,
  51. TypeName = property.PropertyType.Name,
  52. Label = property.GetCustomAttribute<MonitoredPropertyAttribute>()?.Label ?? property.Name,
  53. Description = property.GetCustomAttribute<MonitoredPropertyAttribute>()?.Description ?? string.Empty,
  54. Order = property.GetCustomAttribute<MonitoredPropertyAttribute>()?.Order ?? 0,
  55. _propertyInfo = property
  56. };
  57. monItemGeneral.Items.Add(itemDescriptor);
  58. if (property.GetCustomAttribute<MonitoredPropertyKeyAttribute>() != null)
  59. {
  60. keys.Add(new Tuple<string, int>(property.Name, property.GetCustomAttribute<MonitoredPropertyKeyAttribute>()!.KeyOrder));
  61. }
  62. }
  63. foreach (var key in keys.OrderBy(x => x.Item2))
  64. {
  65. var ord = monItemGeneral.Items.FindIndex(x => x.Name == key.Item1);
  66. if (ord>=0)
  67. monItemGeneral.KeyOrdinals.Add(ord);
  68. }
  69. _generalCache.Add(type.FullName!, monItemGeneral);
  70. }
  71. }
  72. }
  73. #endregion
  74. #region *** Public Operations ***
  75. #endregion
  76. #region *** Protected Operations ***
  77. protected override void OnDisposing()
  78. {
  79. base.OnDisposing();
  80. _generalCache.Clear();
  81. }
  82. protected override void OnTimerData(object? state)
  83. {
  84. }
  85. protected override void OnTimerGeneral(object? state)
  86. {
  87. if (state == null) throw new ArgumentNullException(nameof(state));
  88. var owner = (QMonClient)state;
  89. try
  90. {
  91. var data = new MonGeneral()
  92. {
  93. InstanceIdentifier = owner.InstanceIdentifier,
  94. Items = new List<MonItemGeneral>()
  95. };
  96. data.Items.AddRange(owner._generalCache.Values);
  97. var dataOut = Serialize(data);
  98. UdpClientGeneral.Send(dataOut);
  99. Log(LogSeverityEnum.Trace, $"[{InstanceIdentifier}] Sent General packet size = {dataOut.Length} bytes");
  100. }
  101. catch(Exception ex)
  102. {
  103. Log(LogSeverityEnum.Error, $"[{InstanceIdentifier}] Error sending general data", ex);
  104. }
  105. }
  106. private byte[] Serialize(MonGeneral data)
  107. {
  108. if (data == null) throw new ArgumentNullException(nameof(data));
  109. var json = Binder.SaveToString(data);
  110. return Encoding.UTF8.GetBytes(json);
  111. }
  112. protected override UdpClient CreateUdpClient(Uri targetUri)
  113. {
  114. var ep = new IPEndPoint(IPAddress.Parse(targetUri.DnsSafeHost), targetUri.Port);
  115. var udpClient = new UdpClient();
  116. udpClient.Connect(ep);
  117. return udpClient;
  118. }
  119. protected override void OnOpen()
  120. {
  121. }
  122. protected override void OnClose()
  123. {
  124. }
  125. #endregion
  126. #region *** Nested Types ***
  127. #endregion
  128. }
  129. }