Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

293 lines
14KB

  1. using dotnet_etcd;
  2. using Etcdserverpb;
  3. using HealthMonitor.Common;
  4. using HealthMonitor.Common.helper;
  5. using HealthMonitor.Core.Common.Extensions;
  6. using HealthMonitor.Service.Biz.db;
  7. using HealthMonitor.Service.Etcd;
  8. using HealthMonitor.Service.Sub;
  9. using Microsoft.EntityFrameworkCore.Metadata.Internal;
  10. using Newtonsoft.Json;
  11. using Newtonsoft.Json.Linq;
  12. using System.Threading.Channels;
  13. using TDengineDriver;
  14. using TDengineTMQ;
  15. namespace HealthMonitor.WebApi
  16. {
  17. public class Worker : BackgroundService
  18. {
  19. private readonly ILogger<Worker> _logger;
  20. private readonly IServiceProvider _services;
  21. private readonly TDengineDataSubcribe _tdEngineDataSubcribe;
  22. private readonly PackageProcess _processor;
  23. private readonly TDengineService _serviceTDengine;
  24. private readonly EtcdService _serviceEtcd;
  25. private readonly HttpHelper _httpHelper = default!;
  26. private CancellationTokenSource _tokenSource=default!;
  27. public Worker(ILogger<Worker> logger, IServiceProvider services, PackageProcess processor,TDengineDataSubcribe tdEngineDataSubcribe, TDengineService serviceDengine, HttpHelper httpHelper, EtcdService serviceEtcd)
  28. {
  29. _logger = logger;
  30. _tdEngineDataSubcribe = tdEngineDataSubcribe;
  31. _services = services;
  32. _processor = processor;
  33. _serviceEtcd = serviceEtcd;
  34. _serviceTDengine = serviceDengine;
  35. _httpHelper = httpHelper;
  36. }
  37. public override Task StartAsync(CancellationToken cancellationToken)
  38. {
  39. _logger.LogInformation("------StartAsync");
  40. _tokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
  41. // 创建消费者
  42. // _tdEngineDataSubcribe.CreateConsumer();
  43. return base.StartAsync(cancellationToken);
  44. }
  45. public override Task StopAsync(CancellationToken cancellationToken)
  46. {
  47. _logger.LogInformation("------StopAsync");
  48. _tokenSource.Cancel(); //停止工作线程
  49. // 关闭消费者
  50. // _tdEngineDataSubcribe.CloseConsumer();
  51. return base.StopAsync(cancellationToken);
  52. }
  53. protected override Task ExecuteAsync(CancellationToken stoppingToken)
  54. {
  55. // var processor = _services.GetService<PackageProcess>();
  56. TaskFactory factory = new(_tokenSource.Token);
  57. factory.StartNew(async () =>
  58. {
  59. if (_tokenSource.IsCancellationRequested)
  60. _logger.LogWarning("Worker exit");
  61. _logger.LogInformation("------ResolveAsync");
  62. while (!_tokenSource.IsCancellationRequested)
  63. {
  64. //
  65. await _processor.ResolveAsync().ConfigureAwait(false);
  66. // await _tdEngineDataSubcribe.ProcessMsg();
  67. }
  68. }, TaskCreationOptions.LongRunning);
  69. factory.StartNew(() =>
  70. {
  71. _logger.LogInformation("------_tdEngineDataSubcribe");
  72. while (!_tokenSource.IsCancellationRequested)
  73. {
  74. _tdEngineDataSubcribe.BeginListen(_tokenSource.Token);
  75. }
  76. }, TaskCreationOptions.LongRunning);
  77. Task.Run(() =>
  78. _serviceEtcd.WacthKeysWithPrefixResponseAsync($"health_moniter/schedule_push", WatchEvents)
  79. , stoppingToken);
  80. // watch
  81. //factory.StartNew(() =>
  82. //{
  83. // while (!_tokenSource.IsCancellationRequested)
  84. // {
  85. // //_serviceEtcd.WacthKeysWithPrefixAsync($"health_moniter/schedule_push", watchEvents => WatchEvents(watchEvents));
  86. // _serviceEtcd.WacthKeysWithPrefixResponseAsync($"health_moniter/schedule_push", WatchEvents);
  87. // }
  88. //}, TaskCreationOptions.LongRunning);
  89. // _serviceEtcd.WacthKeysWithPrefixResponseAsync($"health_moniter/schedule_push", WatchEvents);
  90. return Task.Delay(1000, _tokenSource.Token);
  91. }
  92. private void WatchEvents(WatchEvent[] response)
  93. {
  94. foreach (WatchEvent e1 in response)
  95. {
  96. // Console.WriteLine($"{nameof(WatchEventsAsync)} --- {e1.Key}:{e1.Value}:{e1.Type}");
  97. switch (e1.Type.ToString())
  98. {
  99. //case "Put":
  100. // // 获取时间点计算TTL
  101. // break;
  102. case "Delete":
  103. // TTL到了重新计算TTL,下发
  104. Console.WriteLine($"--- {e1.Key}:{e1.Value}:{e1.Type}");
  105. break;
  106. }
  107. }
  108. }
  109. private void WatchEvents(WatchResponse response)
  110. {
  111. response.Events.ToList().ForEach(async e =>
  112. {
  113. switch (e.Type.ToString())
  114. {
  115. case "Put":
  116. // 获取时间点计算TTL
  117. Console.BackgroundColor = ConsoleColor.Blue;
  118. Console.WriteLine($"--- {e.Type}--{e.Kv.Key.ToStringUtf8()}--{e.Kv.Value.ToStringUtf8()}---{DateTime.Now}");
  119. Console.BackgroundColor = ConsoleColor.Black;
  120. break;
  121. case "Delete":
  122. // TTL到了重新计算TTL,下发
  123. Console.BackgroundColor = ConsoleColor.Green;
  124. Console.WriteLine($"--- {e.Type}--{e.Kv.Key.ToStringUtf8()}--{e.Kv.Value.ToStringUtf8()}---{DateTime.Now}");
  125. // var key = $"health_moniter/schedule_push/imei/{bp.Serialno}";
  126. var key = e.Kv.Key.ToStringUtf8();
  127. var imeiDel = key.Split('/')[3];
  128. var schedule_push = await _serviceEtcd.GetValAsync(key).ConfigureAwait(false);
  129. if (string.IsNullOrWhiteSpace(schedule_push))
  130. {
  131. var startTime=DateTime.Now;
  132. // 下发增量值
  133. #region 定时下发增量值
  134. var last= await _serviceTDengine.GetLastAsync("stb_hm_bloodpress_stats_inc", $"serialno='{imeiDel}' order by last_update desc");
  135. var ts = last?[0];
  136. if (DateTime.TryParse(ts?.ToString(),out DateTime newTs))
  137. {
  138. // 7 天有效数据
  139. if (newTs.AddDays(7) > DateTime.Now)
  140. {
  141. Console.WriteLine(ts);
  142. var bpData = new
  143. {
  144. imei = imeiDel,
  145. systolicCalibrationValue = last?[5], //收缩压标定值,值为0 表示不生效
  146. diastolicCalibrationValue = last?[12], //舒张压标定值,值为0表示不生效
  147. systolicIncValue = last?[10], //收缩压显示增量,值为0 表示不生效
  148. diastolicIncValue = last?[17] //舒张压显示增量,值为0 表示不生效
  149. };
  150. var str = JsonConvert.SerializeObject(bpData);
  151. var url = $"http://id.ssjlai.com/webapi/api/Command/SetBloodPressCalibrationConfig";
  152. List<KeyValuePair<string, string>> headers = new()
  153. {
  154. new KeyValuePair<string, string>("AuthKey", "key1")
  155. };
  156. var res = await _httpHelper.HttpToPostAsync(url, bpData, headers).ConfigureAwait(false);
  157. _logger.LogInformation($"向{imeiDel}下发增量值数据:{str},响应:{res}");
  158. var resJToken = JsonConvert.DeserializeObject(res!) as JToken;
  159. if (resJToken!["message"]!.ToString().Equals("ok"))
  160. {
  161. // 注册下次下推
  162. var endTime = DateTime.Now;
  163. #if DEBUG
  164. //long ttl = (long)((60 * 1000-(endTime-startTime).TotalMilliseconds)/1000);
  165. //await _serviceEtcd.PutValAsync(key, imeiDel,ttl, false).ConfigureAwait(false);
  166. var interval = 0;
  167. // 获取当前时间
  168. DateTime now = DateTime.Now;
  169. // 计算距离下一个$interval天后的8点的时间间隔
  170. DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute + 2, 0).AddDays(interval);
  171. TimeSpan timeUntilNextRun = nextRunTime - now;
  172. // 如果当前时间已经超过了8点,将等待到明天后的8点
  173. if (timeUntilNextRun < TimeSpan.Zero)
  174. {
  175. timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromMinutes(1));
  176. nextRunTime += timeUntilNextRun;
  177. }
  178. // var ttl = timeUntilNextRun.TotalMilliseconds;
  179. long ttl = (long)((timeUntilNextRun.TotalMilliseconds - (endTime - startTime).TotalMilliseconds) / 1000);
  180. var data = new
  181. {
  182. imei = imeiDel,
  183. create_time = now.ToString("yyyy-MM-dd HH:mm:ss"),
  184. ttl,
  185. next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss")
  186. };
  187. var result = JsonConvert.SerializeObject(data);
  188. await _serviceEtcd.PutValAsync(key, result, ttl, false).ConfigureAwait(false);
  189. #else
  190. // 每$interval天,晚上8点
  191. var interval = 1;
  192. // 获取当前时间
  193. DateTime now = DateTime.Now;
  194. // 计算距离下一个$interval天后的8点的时间间隔
  195. DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, 20, 0, 0).AddDays(interval);
  196. TimeSpan timeUntilNextRun = nextRunTime - now;
  197. // 如果当前时间已经超过了8点,将等待到明天后的8点
  198. if (timeUntilNextRun < TimeSpan.Zero)
  199. {
  200. timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromDays(1));
  201. nextRunTime += timeUntilNextRun;
  202. }
  203. // var ttl = timeUntilNextRun.TotalMilliseconds;
  204. long ttl = (long)((timeUntilNextRun.TotalMilliseconds-(endTime-startTime).TotalMilliseconds)/1000);
  205. var data = new
  206. {
  207. imei = imeiDel,
  208. create_time = now.ToString("yyyy-MM-dd HH:mm:ss"),
  209. ttl,
  210. next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss")
  211. };
  212. var result = JsonConvert.SerializeObject(data);
  213. await _serviceEtcd.PutValAsync(key, result, ttl, false).ConfigureAwait(false);
  214. #endif
  215. }
  216. else
  217. {
  218. _logger.LogInformation($"错误响应,没有下推数据");
  219. }
  220. Console.WriteLine(str);
  221. }
  222. }
  223. else
  224. {
  225. _logger.LogInformation($"向{imeiDel}准备下推的数据已经失效ts,{ts}");
  226. }
  227. #endregion
  228. //if (imeiDel.Equals("861281060086216"))
  229. //{
  230. // var result = await _httpHelper.HttpToPostAsync(url, data, headers).ConfigureAwait(false);
  231. // _logger.LogInformation($"向{imeiDel}下发增量值数据:{str},响应:{result}");
  232. // Console.WriteLine(str);
  233. //}
  234. Console.BackgroundColor = ConsoleColor.Black;
  235. }
  236. break;
  237. }
  238. });
  239. //if (response.Events.Count == 0)
  240. //{
  241. // Console.WriteLine(response);
  242. //}
  243. //else
  244. //{
  245. // Console.WriteLine($"{response.Events[0].Kv.Key.ToStringUtf8()}:{response.Events.Kv.Value.ToStringUtf8()}");
  246. //}
  247. }
  248. }
  249. }