redis心跳添加
parent
a092d6cbe8
commit
91cb7a72db
|
|
@ -30,7 +30,7 @@ namespace Hopetry.Services
|
||||||
{
|
{
|
||||||
var key = $"{Prefix}{info.MachineId}";
|
var key = $"{Prefix}{info.MachineId}";
|
||||||
var json = JsonConvert.SerializeObject(info);
|
var json = JsonConvert.SerializeObject(info);
|
||||||
await _db.StringSetAsync(key, json, TimeSpan.FromDays(30));
|
await _db.StringSetAsync(key, json, TimeSpan.FromMinutes(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取单个客户端信息
|
// 获取单个客户端信息
|
||||||
|
|
@ -65,6 +65,51 @@ namespace Hopetry.Services
|
||||||
return await _db.KeyDeleteAsync($"{Prefix}{machineId}");
|
return await _db.KeyDeleteAsync($"{Prefix}{machineId}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增心跳键前缀
|
||||||
|
private const string HeartbeatPrefix = "heartbeat:";
|
||||||
|
|
||||||
|
// 更新客户端心跳(核心新增方法)
|
||||||
|
public async Task UpdateClientHeartbeatAsync(string machineId)
|
||||||
|
{
|
||||||
|
// 同时更新两个键的过期时间:
|
||||||
|
// 1. 客户端信息键(保持长期有效)
|
||||||
|
// 2. 心跳状态键(短期存活检测)
|
||||||
|
var tasks = new List<Task>
|
||||||
|
{
|
||||||
|
// 刷新客户端信息过期时间(30天)
|
||||||
|
_db.KeyExpireAsync($"{Prefix}{machineId}", TimeSpan.FromMinutes(5)),
|
||||||
|
|
||||||
|
// 设置/更新心跳状态(带5分钟过期)
|
||||||
|
_db.StringSetAsync(
|
||||||
|
$"{HeartbeatPrefix}{machineId}",
|
||||||
|
DateTime.UtcNow.ToString("o"),
|
||||||
|
expiry: TimeSpan.FromMinutes(5)
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
await Task.WhenAll(tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取所有活跃客户端ID(基于心跳键)
|
||||||
|
public async Task<List<string>> GetActiveClientIdsAsync()
|
||||||
|
{
|
||||||
|
var endpoints = _redis.GetEndPoints();
|
||||||
|
var server = _redis.GetServer(endpoints.First());
|
||||||
|
|
||||||
|
// 注意:生产环境应改用SCAN
|
||||||
|
var heartbeatKeys = server.Keys(pattern: $"{HeartbeatPrefix}*");
|
||||||
|
|
||||||
|
return heartbeatKeys
|
||||||
|
.Select(k => k.ToString().Substring(HeartbeatPrefix.Length))
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查客户端是否活跃
|
||||||
|
public async Task<bool> IsClientActiveAsync(string machineId)
|
||||||
|
{
|
||||||
|
return await _db.KeyExistsAsync($"{HeartbeatPrefix}{machineId}");
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_redis?.Dispose();
|
_redis?.Dispose();
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ using Minio.Exceptions;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using Microsoft.VisualBasic;
|
using Microsoft.VisualBasic;
|
||||||
using log4net.Util;
|
|
||||||
|
|
||||||
namespace HeBianGu.App.Disk
|
namespace HeBianGu.App.Disk
|
||||||
{
|
{
|
||||||
|
|
@ -119,6 +118,7 @@ namespace HeBianGu.App.Disk
|
||||||
private IConfiguration config;
|
private IConfiguration config;
|
||||||
private SemaphoreSlim _semaphore = new SemaphoreSlim(5);
|
private SemaphoreSlim _semaphore = new SemaphoreSlim(5);
|
||||||
private Timer _progressTimer;
|
private Timer _progressTimer;
|
||||||
|
private Timer _heartbeatTimer ;
|
||||||
private bool _isTimerRunning = false;
|
private bool _isTimerRunning = false;
|
||||||
private object _timerLock = new object();
|
private object _timerLock = new object();
|
||||||
private bool _isUploading = false; // 新增:标记是否有上传任务正在运行
|
private bool _isUploading = false; // 新增:标记是否有上传任务正在运行
|
||||||
|
|
@ -129,6 +129,7 @@ namespace HeBianGu.App.Disk
|
||||||
private int regionCount = 0;
|
private int regionCount = 0;
|
||||||
private ExplorerMinIOBehavior _explorerBehavior;
|
private ExplorerMinIOBehavior _explorerBehavior;
|
||||||
private MinIOSearchBehavior _minioBehavior;
|
private MinIOSearchBehavior _minioBehavior;
|
||||||
|
private Hopetry.Provider.SystemInfo systemInfo;
|
||||||
// 配置Redis连接
|
// 配置Redis连接
|
||||||
private RedisService redis = new RedisService("175.27.168.120:6050,password=HopetryRedis1406,connectRetry=3");
|
private RedisService redis = new RedisService("175.27.168.120:6050,password=HopetryRedis1406,connectRetry=3");
|
||||||
|
|
||||||
|
|
@ -150,11 +151,14 @@ namespace HeBianGu.App.Disk
|
||||||
DeleteFolderCommand = new AsyncRelayCommand(async () => await DeleteSelectedItemsAsync());
|
DeleteFolderCommand = new AsyncRelayCommand(async () => await DeleteSelectedItemsAsync());
|
||||||
DownloadCommand = new AsyncRelayCommand(async () => await DoDownloadCommand());
|
DownloadCommand = new AsyncRelayCommand(async () => await DoDownloadCommand());
|
||||||
SelectDirCommand = new CustomCommand(async () => await DoSelectDirCommand());
|
SelectDirCommand = new CustomCommand(async () => await DoSelectDirCommand());
|
||||||
|
systemInfo = SystemInfoCollector.Collect();
|
||||||
//SelectItemsCommand = new AsyncRelayCommand(async () => await RelayCommand<SystemInfoModel>(SelectItem)SelectItem());
|
//SelectItemsCommand = new AsyncRelayCommand(async () => await RelayCommand<SystemInfoModel>(SelectItem)SelectItem());
|
||||||
// 初始化Timer
|
// 初始化Timer
|
||||||
_progressTimer = new Timer(1000);
|
_progressTimer = new Timer(1000);
|
||||||
_progressTimer.Elapsed += UpdateProgress;
|
_progressTimer.Elapsed += UpdateProgress;
|
||||||
_sendViewModel.UpLoadItems.CollectionChanged += (s, e) => { _sendViewModel.UpdateUploadingItems(); };
|
_heartbeatTimer = new Timer(30_000);
|
||||||
|
_heartbeatTimer.Elapsed += async (s, e) => await SendHeartbeatAsync();
|
||||||
|
_sendViewModel.UpLoadItems.CollectionChanged += (s, e) => { _sendViewModel.UpdateUploadingItems(); };
|
||||||
//加载上传完成列表
|
//加载上传完成列表
|
||||||
GetCompletedFiles();
|
GetCompletedFiles();
|
||||||
}
|
}
|
||||||
|
|
@ -210,6 +214,22 @@ namespace HeBianGu.App.Disk
|
||||||
Application.Current.Dispatcher.Invoke(() => { _sendViewModel.Progress = progress; });
|
Application.Current.Dispatcher.Invoke(() => { _sendViewModel.Progress = progress; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//上传redis心跳检测
|
||||||
|
private async Task SendHeartbeatAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 上报心跳并更新客户端信息
|
||||||
|
//await redis.StoreClientInfoAsync(systemInfo);
|
||||||
|
await redis.UpdateClientHeartbeatAsync(systemInfo.MachineId);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// 处理网络异常等
|
||||||
|
Debug.WriteLine($"心跳上报失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void StartProgressTimer()
|
private void StartProgressTimer()
|
||||||
{
|
{
|
||||||
lock (_timerLock)
|
lock (_timerLock)
|
||||||
|
|
@ -217,6 +237,7 @@ namespace HeBianGu.App.Disk
|
||||||
if (!_isTimerRunning)
|
if (!_isTimerRunning)
|
||||||
{
|
{
|
||||||
_progressTimer.Start();
|
_progressTimer.Start();
|
||||||
|
_heartbeatTimer.Start();
|
||||||
_isTimerRunning = true;
|
_isTimerRunning = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -229,6 +250,7 @@ namespace HeBianGu.App.Disk
|
||||||
if (_isTimerRunning)
|
if (_isTimerRunning)
|
||||||
{
|
{
|
||||||
_progressTimer.Stop();
|
_progressTimer.Stop();
|
||||||
|
_heartbeatTimer.Stop();
|
||||||
_isTimerRunning = false;
|
_isTimerRunning = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -401,7 +423,7 @@ namespace HeBianGu.App.Disk
|
||||||
_isUploading = true;
|
_isUploading = true;
|
||||||
StartProgressTimer();
|
StartProgressTimer();
|
||||||
// 收集系统信息
|
// 收集系统信息
|
||||||
var systemInfo = SystemInfoCollector.Collect();
|
//var systemInfo = SystemInfoCollector.Collect();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 存储到Redis
|
// 存储到Redis
|
||||||
|
|
@ -877,8 +899,8 @@ namespace HeBianGu.App.Disk
|
||||||
{
|
{
|
||||||
await DeleteMinIOItems(selectedItems);
|
await DeleteMinIOItems(selectedItems);
|
||||||
|
|
||||||
_explorerBehavior.RefreshMinIOPath(CurrentMinIOPath);
|
|
||||||
MessageBox.Show($"已成功删除 {selectedItems.Count} 个项目");
|
MessageBox.Show($"已成功删除 {selectedItems.Count} 个项目");
|
||||||
|
_explorerBehavior.RefreshMinIOPath(CurrentMinIOPath);
|
||||||
SelectedItems.Clear();
|
SelectedItems.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue