168 lines
5.3 KiB
C#
168 lines
5.3 KiB
C#
using System.Net.NetworkInformation;
|
|
using WorkCameraExport.Services.Interfaces;
|
|
|
|
namespace WorkCameraExport.Services
|
|
{
|
|
/// <summary>
|
|
/// 网络监控服务 - 负责检测网络连接状态
|
|
/// </summary>
|
|
public class NetworkMonitor : IDisposable
|
|
{
|
|
private readonly ILogService? _logService;
|
|
private bool _isNetworkAvailable;
|
|
private bool _disposed;
|
|
|
|
/// <summary>
|
|
/// 网络状态变化事件
|
|
/// </summary>
|
|
public event EventHandler<NetworkStatusChangedEventArgs>? NetworkStatusChanged;
|
|
|
|
/// <summary>
|
|
/// 当前网络是否可用
|
|
/// </summary>
|
|
public bool IsNetworkAvailable => _isNetworkAvailable;
|
|
|
|
public NetworkMonitor(ILogService? logService = null)
|
|
{
|
|
_logService = logService;
|
|
_isNetworkAvailable = NetworkInterface.GetIsNetworkAvailable();
|
|
|
|
// 订阅网络状态变化事件
|
|
NetworkChange.NetworkAvailabilityChanged += OnNetworkAvailabilityChanged;
|
|
NetworkChange.NetworkAddressChanged += OnNetworkAddressChanged;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查网络是否可用
|
|
/// </summary>
|
|
public bool CheckNetworkAvailability()
|
|
{
|
|
try
|
|
{
|
|
_isNetworkAvailable = NetworkInterface.GetIsNetworkAvailable();
|
|
return _isNetworkAvailable;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logService?.Error("检查网络状态失败", ex);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查是否可以连接到指定服务器
|
|
/// </summary>
|
|
public async Task<bool> CheckServerConnectivityAsync(string serverUrl, int timeoutMs = 5000)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(serverUrl))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
try
|
|
{
|
|
using var httpClient = new HttpClient
|
|
{
|
|
Timeout = TimeSpan.FromMilliseconds(timeoutMs)
|
|
};
|
|
|
|
var uri = new Uri(serverUrl);
|
|
var response = await httpClient.GetAsync($"{uri.Scheme}://{uri.Host}:{uri.Port}/");
|
|
return response.IsSuccessStatusCode ||
|
|
response.StatusCode == System.Net.HttpStatusCode.Unauthorized ||
|
|
response.StatusCode == System.Net.HttpStatusCode.NotFound;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logService?.Warn($"无法连接到服务器 {serverUrl}: {ex.Message}");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 使用 Ping 检查网络连通性
|
|
/// </summary>
|
|
public async Task<bool> PingAsync(string host = "8.8.8.8", int timeoutMs = 3000)
|
|
{
|
|
try
|
|
{
|
|
using var ping = new Ping();
|
|
var reply = await ping.SendPingAsync(host, timeoutMs);
|
|
return reply.Status == IPStatus.Success;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logService?.Warn($"Ping 失败: {ex.Message}");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 网络可用性变化事件处理
|
|
/// </summary>
|
|
private void OnNetworkAvailabilityChanged(object? sender, NetworkAvailabilityEventArgs e)
|
|
{
|
|
var previousState = _isNetworkAvailable;
|
|
_isNetworkAvailable = e.IsAvailable;
|
|
|
|
if (previousState != _isNetworkAvailable)
|
|
{
|
|
_logService?.Info($"网络状态变化: {(e.IsAvailable ? "已连接" : "已断开")}");
|
|
NetworkStatusChanged?.Invoke(this, new NetworkStatusChangedEventArgs(e.IsAvailable));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 网络地址变化事件处理
|
|
/// </summary>
|
|
private void OnNetworkAddressChanged(object? sender, EventArgs e)
|
|
{
|
|
var newState = NetworkInterface.GetIsNetworkAvailable();
|
|
var previousState = _isNetworkAvailable;
|
|
_isNetworkAvailable = newState;
|
|
|
|
if (previousState != newState)
|
|
{
|
|
_logService?.Info($"网络地址变化,当前状态: {(newState ? "已连接" : "已断开")}");
|
|
NetworkStatusChanged?.Invoke(this, new NetworkStatusChangedEventArgs(newState));
|
|
}
|
|
}
|
|
|
|
#region IDisposable
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
if (!_disposed)
|
|
{
|
|
if (disposing)
|
|
{
|
|
NetworkChange.NetworkAvailabilityChanged -= OnNetworkAvailabilityChanged;
|
|
NetworkChange.NetworkAddressChanged -= OnNetworkAddressChanged;
|
|
}
|
|
_disposed = true;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// 网络状态变化事件参数
|
|
/// </summary>
|
|
public class NetworkStatusChangedEventArgs : EventArgs
|
|
{
|
|
public bool IsAvailable { get; }
|
|
|
|
public NetworkStatusChangedEventArgs(bool isAvailable)
|
|
{
|
|
IsAvailable = isAvailable;
|
|
}
|
|
}
|
|
}
|