using LY.App.Extensions.DI;
using StackExchange.Redis;
using System.Text.Json;
namespace LY.App.Common.Redis
{
///
/// redis 连接服务
///
public class RedisService
{
private readonly IDatabase _db;
private readonly IServer _redis;
///
/// 构造函数
///
///
public RedisService(string connectionString)
{
var redis = ConnectionMultiplexer.Connect(connectionString);
_db = redis.GetDatabase();
}
///
/// 泛型存储数据到 Redis
///
public async Task SetAsync(string key, T value, TimeSpan? expiry = null)
{
string jsonData = JsonSerializer.Serialize(value);
return await _db.StringSetAsync(key, jsonData, expiry);
}
///
/// 泛型获取数据
///
public async Task GetAsync(string key)
{
string jsonData = await _db.StringGetAsync(key);
return jsonData is not null ? JsonSerializer.Deserialize(jsonData) : default;
}
///
/// 模糊 查询所有 Key
///
///
///
public Task> GetAllKeysAsync(string pattern)
{
var redis = _db.Multiplexer;
var keys = new List();
foreach (var endPoint in redis.GetEndPoints())
{
var server = redis.GetServer(endPoint);
if (!server.IsConnected)
continue;
// 使用 SCAN 获取匹配的 key,避免 KEYS 阻塞
var scanKeys = server.Keys(pattern: pattern, pageSize: 1000);
keys.AddRange(scanKeys);
}
return Task.FromResult(keys);
//var result = new Dictionary();
//if (keys.Count > 0)
//{
// // 一次批量获取 value
// var values = await _db.StringGetAsync(keys.ToArray());
// for (int i = 0; i < keys.Count; i++)
// {
// if (values[i].HasValue)
// {
// result[keys[i]] = values[i];
// }
// }
//}
//return result;
}
///
/// 删除 Key
///
public async Task DeleteAsync(string key)
{
return await _db.KeyDeleteAsync(key);
}
///
/// 检查 Key 是否存在
///
public async Task ExistsAsync(string key)
{
return await _db.KeyExistsAsync(key);
}
///
/// 获取数据,如果不存在则从数据源获取并存入 Redis
///
/// 数据类型
/// Redis Key
/// 数据源方法
/// 可选的过期时间
/// 获取到的值
public async Task GetOrSetAsync(string key, Func> factory, TimeSpan? expiry = null)
{
var value = await GetAsync(key);
if (value is not null)
{
return value;
}
value = await factory();
if (value is not null)
{
await SetAsync(key, value, expiry);
}
return value;
}
}
}