QMonReceiver.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. using System.Collections.Concurrent;
  2. using System.Net;
  3. using System.Net.Sockets;
  4. using System.Text;
  5. using System.Text.Json;
  6. using Quadarax.Foundation.Core.Logging;
  7. namespace qmonlib
  8. {
  9. public delegate void GeneralDataReceivedDelegate(MonGeneral general);
  10. public class QMonReceiver : QMonHostBase<QMonReceiverConfiguration>
  11. {
  12. #region *** Properties ***
  13. protected override Uri UriGeneral => Configuration.SourceUriGeneral;
  14. protected override Uri UriData => Configuration.SourceUriData;
  15. protected override TimeSpan IntervalGeneral => Configuration.GeneralReceiverInterval;
  16. protected override TimeSpan? IntervalData => null;
  17. public MonGeneral[] AvailableGeneral => _generalCache.Values.Select(x=>x.Data).ToArray();
  18. #endregion
  19. #region *** Fields ***
  20. private GeneralDataReceivedDelegate _generalReceivedCallback;
  21. private bool _isReceivingGeneral;
  22. private CancellationTokenSource _dataReceiverCancel;
  23. private IDictionary<string, MonReceiverGeneralCahedItem> _generalCache = new ConcurrentDictionary<string, MonReceiverGeneralCahedItem>();
  24. #endregion
  25. #region *** Constructors ***
  26. public QMonReceiver(QMonReceiverConfiguration configuration, ILogger logger, GeneralDataReceivedDelegate generalDataReceivedCallback = null) : base(configuration, logger)
  27. {
  28. _generalReceivedCallback = generalDataReceivedCallback;
  29. }
  30. #endregion
  31. #region *** Private overrides ***
  32. protected override void OnOpen()
  33. {
  34. var _dataReceiverCancel = new CancellationTokenSource();
  35. new Thread(() =>
  36. {
  37. try
  38. {
  39. OnThreadData(_dataReceiverCancel.Token);
  40. }
  41. catch (OperationCanceledException)
  42. {
  43. Log(LogSeverityEnum.Info, $"Data receiver thread on {UriData} unexpected stopped");
  44. }
  45. }).Start();
  46. Log(LogSeverityEnum.Info, $"Data receiver thread on {UriData} started");
  47. }
  48. protected override void OnClose()
  49. {
  50. _dataReceiverCancel?.Cancel();
  51. Log(LogSeverityEnum.Info, $"Data receiver thread on {UriData} stopped");
  52. }
  53. protected override void OnTimerData(object? state)
  54. {
  55. throw new NotSupportedException("Timer is not allowed in receiver.");
  56. }
  57. protected override void OnTimerGeneral(object? state)
  58. {
  59. if (state == null) throw new ArgumentNullException(nameof(state));
  60. var owner = (QMonReceiver)state;
  61. if (owner._isReceivingGeneral) return;
  62. owner._isReceivingGeneral = true;
  63. try
  64. {
  65. var remoteEndPoint = new IPEndPoint(IPAddress.Parse(owner.UriGeneral.DnsSafeHost), owner.UriGeneral.Port);
  66. var data = UdpClientGeneral.Receive(ref remoteEndPoint);
  67. var general = (MonGeneral) Binder.LoadFromString(Encoding.UTF8.GetString(data), typeof(MonGeneral));
  68. Log(LogSeverityEnum.Debug,
  69. $"[ReceiverGeneral] receive general data from '{remoteEndPoint}' [{general.InstanceIdentifier}] size={data.Length} bytes.");
  70. _generalCache.TryAdd(general.InstanceIdentifier, new MonReceiverGeneralCahedItem(DateTime.Now, remoteEndPoint, general));
  71. _generalReceivedCallback?.Invoke(general);
  72. }
  73. catch (Exception e)
  74. {
  75. Log(LogSeverityEnum.Error, $"[ReceiverGeneral] Error receiving general data", e);
  76. }
  77. finally
  78. {
  79. owner._isReceivingGeneral = false;
  80. }
  81. }
  82. private void OnThreadData(CancellationToken cancellation)
  83. {
  84. if (cancellation == null) throw new ArgumentNullException(nameof(cancellation));
  85. if (cancellation.IsCancellationRequested)
  86. {
  87. Log(LogSeverityEnum.Debug, $"[ReceiverData] Cancellation token detected on listener '{UriData}'.");
  88. }
  89. try
  90. {
  91. if (UdpClientData.Available==0) return;
  92. var remoteEndPoint = new IPEndPoint(IPAddress.Parse(this.UriData.DnsSafeHost), this.UriData.Port);
  93. var data = UdpClientData.Receive(ref remoteEndPoint);
  94. var jsonData = JsonDocument.Parse(Encoding.UTF8.GetString(data));
  95. Log(LogSeverityEnum.Debug, $"[ReceiverData] receive monitor data from '{remoteEndPoint}' size={data.Length} bytes.");
  96. }
  97. catch (Exception e)
  98. {
  99. Log(LogSeverityEnum.Error, $"[ReceiverData] Error receiving monitor data", e);
  100. }
  101. }
  102. protected override UdpClient CreateUdpClient(Uri targetUri)
  103. {
  104. var udpClient = new UdpClient(targetUri.Port);
  105. return udpClient;
  106. }
  107. protected override void OnDisposing()
  108. {
  109. _dataReceiverCancel?.Cancel();
  110. _dataReceiverCancel?.Dispose();
  111. _dataReceiverCancel = null;
  112. base.OnDisposing();
  113. }
  114. #endregion
  115. }
  116. }