更新项目配置,新增设备同步模块,优化WebSocket和Swagger配置,增强SCADA系统的免登录接口,支持数据字典项和登录日志的免登录查询与记录。调整Java编译设置,确保更好的开发体验。
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Prism.Events;
|
||||
using System.Net.Http;
|
||||
using YY.Admin.Core.Events;
|
||||
using YY.Admin.Core.Services;
|
||||
|
||||
namespace YY.Admin.Infrastructure.Network;
|
||||
|
||||
public class NetworkMonitor : INetworkMonitor
|
||||
{
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly SemaphoreSlim _startLock = new(1, 1);
|
||||
private Task? _loopTask;
|
||||
private CancellationTokenSource? _cts;
|
||||
private volatile bool _isOnline;
|
||||
|
||||
public NetworkMonitor(
|
||||
IHttpClientFactory httpClientFactory,
|
||||
IConfiguration configuration,
|
||||
IEventAggregator eventAggregator)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_configuration = configuration;
|
||||
_eventAggregator = eventAggregator;
|
||||
}
|
||||
|
||||
public bool IsOnline => _isOnline;
|
||||
|
||||
public event Action<bool>? StatusChanged;
|
||||
|
||||
public async Task StartAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
await _startLock.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
if (_cts != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
||||
_loopTask = Task.Run(() => MonitorLoopAsync(_cts.Token), _cts.Token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_startLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task MonitorLoopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
using var timer = new PeriodicTimer(TimeSpan.FromSeconds(10));
|
||||
while (await timer.WaitForNextTickAsync(cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
var online = await ProbeAsync(cancellationToken).ConfigureAwait(false);
|
||||
if (online == _isOnline)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_isOnline = online;
|
||||
StatusChanged?.Invoke(online);
|
||||
_eventAggregator.GetEvent<NetworkStatusChangedEvent>().Publish(new NetworkStatusChangedPayload
|
||||
{
|
||||
IsOnline = online,
|
||||
ChangedAt = DateTime.UtcNow
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> ProbeAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var baseUrl = _configuration.GetValue<string>("JeecgIntegration:BaseUrl")?.TrimEnd('/');
|
||||
if (string.IsNullOrWhiteSpace(baseUrl))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 探活策略:优先调用免登录接口,失败后再降级到健康检查接口
|
||||
var probeUrls = new[]
|
||||
{
|
||||
$"{baseUrl}/sys/user/scada/queryUser?current=1&pageSize=1",
|
||||
$"{baseUrl}/sys/dict/scada/queryDictItem?pageNo=1&pageSize=1",
|
||||
$"{baseUrl}/actuator/health"
|
||||
};
|
||||
|
||||
using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
||||
timeoutCts.CancelAfter(TimeSpan.FromSeconds(3));
|
||||
var client = _httpClientFactory.CreateClient("JeecgApi");
|
||||
foreach (var url in probeUrls)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var req = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
using var resp = await client.SendAsync(req, timeoutCts.Token).ConfigureAwait(false);
|
||||
if (resp.IsSuccessStatusCode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 当前探活地址失败后继续尝试下一个降级地址
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user