SignalRIESHybridClientHub.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. using Microsoft.AspNetCore.SignalR;
  2. using Microsoft.AspNetCore.SignalR.Client;
  3. using System.Text;
  4. using System.Text.Json;
  5. using System.Text.Json.Nodes;
  6. using System.Web;
  7. using TEAMModelOS.SDK;
  8. using TEAMModelOS.SDK.DI;
  9. using TEAMModelOS.SDK.DI.Device;
  10. using TEAMModelOS.SDK.Extension;
  11. using static Azure.Core.HttpHeader;
  12. namespace IESHybridCloud.Services
  13. {
  14. public class SignalRIESHybridClientHub : BackgroundService, IDisposable
  15. {
  16. private readonly IConfiguration _configuration;
  17. private readonly ILogger<SignalRIESHybridClientHub> _logger;
  18. private TEAMModelOS.SDK.HybridClient? device;
  19. private readonly CoreDevice _device;
  20. private readonly IHttpClientFactory _httpClientFactory;
  21. private readonly BackgroundWorkerQueue _backgroundWorkerQueue;
  22. private readonly AzureSignalRFactory _azureSignalRFactory;
  23. public SignalRIESHybridClientHub(AzureSignalRFactory azureSignalRFactory,BackgroundWorkerQueue backgroundWorkerQueue, IConfiguration configuration, ILogger<SignalRIESHybridClientHub> logger, IHttpClientFactory httpClientFactory, CoreDevice device)
  24. {
  25. _configuration=configuration;
  26. _logger=logger;
  27. _httpClientFactory=httpClientFactory;
  28. _device = device;
  29. _backgroundWorkerQueue=backgroundWorkerQueue;
  30. _azureSignalRFactory=azureSignalRFactory;
  31. }
  32. protected async override Task ExecuteAsync(CancellationToken stoppingToken)
  33. {
  34. var coreDevice = await _device.GetCoreDevice();
  35. device=coreDevice.ToJsonString().ToObject<TEAMModelOS.SDK.HybridClient>();
  36. string clientid = device.deviceId!;
  37. string? CenterUrl = _configuration.GetSection("HybridClient:CenterUrl").Value;
  38. long Timeout = _configuration.GetValue<long>("HybridClient:Timeout");
  39. long Delay = _configuration.GetValue<long>("HybridClient:Delay");
  40. device.timeout = Timeout;
  41. device.delay = Delay;
  42. await StartHubConnectionAsync(clientid, CenterUrl);
  43. }
  44. private async Task StartHubConnectionAsync(string clientid, string? CenterUrl)
  45. {
  46. //重写重连策略,防止服务端更新,断线后,客户端达到最大连接次数,依然连线不上服务端。
  47. var reconnectPolicy = new ExponentialBackoffReconnectPolicy(TimeSpan.FromSeconds(10), _logger); // 尝试重连的最大次数,这里使用 int.MaxValue 表示无限次
  48. reconnectPolicy.MaxRetryCount = int.MaxValue;
  49. //HubConnection hubConnection = new HubConnectionBuilder()
  50. // .WithUrl($"https://localhost:5001/hub/hybrid-cloud?grant_type={HybridConstant.grant_type}&clientid={clientid}&device={HttpUtility.UrlEncode(device.ToJsonString(), Encoding.Unicode)}") //only one slash
  51. // .WithAutomaticReconnect(reconnectPolicy)
  52. // .ConfigureLogging(logging =>
  53. // {
  54. // logging.SetMinimumLevel(LogLevel.Information);
  55. // logging.AddConsole();
  56. // })
  57. // .Build();
  58. try
  59. {
  60. //hubConnection.On<ConnectionMessage>("ReceiveConnection", (message) =>
  61. //{
  62. // _logger.LogInformation($"连接成功:{message.ToJsonString()}");
  63. // //重置重连次数。
  64. // reconnectPolicy.Reset();
  65. //});
  66. //hubConnection.On<JsonElement>("ReceiveMessage", async (message) =>
  67. //{
  68. // {
  69. // _logger.LogInformation($"获得推送数据,{message.ToJsonString()}");
  70. // }
  71. //});ieshybridcloudhub
  72. //await hubConnection.StartAsync();
  73. var hub = _azureSignalRFactory.GetServiceManager().GetHubContext($"/ieshybridcloudhub");
  74. await hub.Clients.User(device.deviceId).SendCoreAsync("ReceiveMessage", new[]{new {
  75. connectionId = "1",
  76. to = "2",
  77. groupname ="3",
  78. sender = device.deviceId,
  79. text = device.ToJsonString()
  80. }});
  81. }
  82. catch (Exception ex)
  83. {
  84. _logger.LogError("初次启动连接SignalR失败,等待重连......");
  85. int retryCount = 0;
  86. const int maxRetries = 360;
  87. const int retryDelaySeconds = 10;
  88. while (retryCount < maxRetries)
  89. {
  90. try
  91. {
  92. await Task.Delay(retryDelaySeconds * 1000); // 等待一段时间后重试
  93. // await hubConnection.StartAsync();
  94. _logger.LogInformation("SignalR连接成功(重试后)!");
  95. break; // 连接成功,退出循环
  96. }
  97. catch (Exception retryEx)
  98. {
  99. retryCount++;
  100. _logger.LogInformation($"SignalR连接重试失败: {retryEx.Message}。重试次数: {retryCount}/{maxRetries}");
  101. // 可以在这里决定是否因为某种原因停止重试
  102. if (retryCount == maxRetries)
  103. {
  104. _logger.LogInformation("达到最大重试次数,停止重试。");
  105. break;
  106. }
  107. }
  108. }
  109. }
  110. }
  111. public async Task<(int status, string msg, JsonNode? data)> ReceiveMessage(JsonNode data)
  112. {
  113. int status = 0;
  114. string msg = string.Empty;
  115. _backgroundWorkerQueue.QueueBackgroundWorkItem(async task =>
  116. {
  117. var pk= data["pk"];
  118. });
  119. return (status, msg, data);
  120. }
  121. }
  122. public class ExponentialBackoffReconnectPolicy : IRetryPolicy
  123. {
  124. private readonly TimeSpan _retryInterval;
  125. private int _retryCount;
  126. public int MaxRetryCount { get; set; } = int.MaxValue;
  127. public readonly ILogger<SignalRIESHybridClientHub> _logger;
  128. public ExponentialBackoffReconnectPolicy(TimeSpan retryInterval, ILogger<SignalRIESHybridClientHub> logger)
  129. {
  130. _retryInterval = retryInterval;
  131. _retryCount = 0;
  132. _logger = logger;
  133. }
  134. public TimeSpan? NextRetryDelay(RetryContext retryContext)
  135. {
  136. _logger.LogInformation($"重连次数: {_retryCount}");
  137. if (_retryCount < MaxRetryCount)
  138. {
  139. _retryCount++;
  140. // 计算下一次重连的延迟时间
  141. return _retryInterval;
  142. }
  143. return null; // 达到最大重连次数后不再重连
  144. }
  145. public void Reset()
  146. {
  147. _retryCount = 0;
  148. }
  149. }
  150. }