329 lines
9.0 KiB
C#
329 lines
9.0 KiB
C#
using LiveForum.Code.Redis.Contract;
|
||
|
||
using Microsoft.Extensions.Caching.Distributed;
|
||
using Microsoft.Extensions.Logging;
|
||
|
||
using StackExchange.Redis;
|
||
|
||
using System.Text.Json;
|
||
|
||
namespace LiveForum.Code
|
||
{
|
||
/// <summary>
|
||
/// Redis缓存服务实现
|
||
/// </summary>
|
||
public class RedisService : IRedisService
|
||
{
|
||
|
||
private readonly ConnectionMultiplexer _redis;
|
||
private readonly ILogger<RedisService> _logger;
|
||
|
||
public RedisService(ConnectionMultiplexer redis, ILogger<RedisService> logger)
|
||
{
|
||
_redis = redis;
|
||
_logger = logger;
|
||
}
|
||
private IDatabase Db => _redis.GetDatabase();
|
||
|
||
public async Task<IDatabase> GetDatabaseAsync()
|
||
{
|
||
try
|
||
{
|
||
return await Task.FromResult(Db);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "获取Redis数据库失败");
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task SetAsync(string key, string value, TimeSpan? expiration = null)
|
||
{
|
||
try
|
||
{
|
||
if (expiration.HasValue)
|
||
{
|
||
await Db.StringSetAsync(key, value, expiration.Value);
|
||
}
|
||
else
|
||
{
|
||
await Db.StringSetAsync(key, value);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "设置Redis缓存失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task SetAsync<T>(string key, T value, TimeSpan? expiration = null)
|
||
{
|
||
try
|
||
{
|
||
var jsonValue = JsonSerializer.Serialize(value);
|
||
if (expiration.HasValue)
|
||
{
|
||
await Db.StringSetAsync(key, jsonValue, expiration.Value);
|
||
}
|
||
else
|
||
{
|
||
await Db.StringSetAsync(key, jsonValue);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "设置Redis缓存失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<string?> GetAsync(string key)
|
||
{
|
||
try
|
||
{
|
||
var value = await Db.StringGetAsync(key);
|
||
return value.HasValue ? value.ToString() : null;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "获取Redis缓存失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<T?> GetAsync<T>(string key)
|
||
{
|
||
try
|
||
{
|
||
var value = await Db.StringGetAsync(key);
|
||
if (!value.HasValue)
|
||
{
|
||
return default(T);
|
||
}
|
||
|
||
return JsonSerializer.Deserialize<T>(value.ToString());
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "获取Redis缓存失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task RemoveAsync(string key)
|
||
{
|
||
try
|
||
{
|
||
await Db.KeyDeleteAsync(key);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "删除Redis缓存失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<bool> ExistsAsync(string key)
|
||
{
|
||
try
|
||
{
|
||
return await Db.KeyExistsAsync(key);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "检查Redis键是否存在失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task SetExpirationAsync(string key, TimeSpan expiration)
|
||
{
|
||
try
|
||
{
|
||
await Db.KeyExpireAsync(key, expiration);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "设置Redis键过期时间失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<TimeSpan?> GetExpirationAsync(string key)
|
||
{
|
||
try
|
||
{
|
||
return await Db.KeyTimeToLiveAsync(key);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "获取Redis键剩余过期时间失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<long> IncrementAsync(string key)
|
||
{
|
||
try
|
||
{
|
||
return await Db.StringIncrementAsync(key);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "Redis自增失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<long> DecrementAsync(string key)
|
||
{
|
||
try
|
||
{
|
||
return await Db.StringDecrementAsync(key);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "Redis自减失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<long> StringGetInt64Async(string key)
|
||
{
|
||
try
|
||
{
|
||
var value = await Db.StringGetAsync(key);
|
||
if (!value.HasValue)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
if (long.TryParse(value.ToString(), out var result))
|
||
{
|
||
return result;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "获取Redis整数值失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<bool> StringSetAsync(string key, long value, TimeSpan? expiration = null)
|
||
{
|
||
try
|
||
{
|
||
if (expiration.HasValue)
|
||
{
|
||
return await Db.StringSetAsync(key, value, expiration.Value);
|
||
}
|
||
else
|
||
{
|
||
return await Db.StringSetAsync(key, value);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "设置Redis整数值失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<bool> SetAddAsync(string key, RedisValue value)
|
||
{
|
||
try
|
||
{
|
||
return await Db.SetAddAsync(key, value);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "Redis Set添加元素失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<bool> SetRemoveAsync(string key, RedisValue value)
|
||
{
|
||
try
|
||
{
|
||
return await Db.SetRemoveAsync(key, value);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "Redis Set移除元素失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<bool> SetContainsAsync(string key, RedisValue value)
|
||
{
|
||
try
|
||
{
|
||
return await Db.SetContainsAsync(key, value);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "检查Redis Set是否包含元素失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<bool> HashSetAsync(string key, RedisValue field, RedisValue value)
|
||
{
|
||
try
|
||
{
|
||
return await Db.HashSetAsync(key, field, value);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "Redis Hash设置字段失败,Key: {Key}, Field: {Field}", key, field);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<RedisValue> HashGetAsync(string key, RedisValue field)
|
||
{
|
||
try
|
||
{
|
||
return await Db.HashGetAsync(key, field);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "Redis Hash获取字段失败,Key: {Key}, Field: {Field}", key, field);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<HashEntry[]> HashGetAllAsync(string key)
|
||
{
|
||
try
|
||
{
|
||
return await Db.HashGetAllAsync(key);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "获取Redis Hash所有字段失败,Key: {Key}", key);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<bool> HashDeleteAsync(string key, RedisValue field)
|
||
{
|
||
try
|
||
{
|
||
return await Db.HashDeleteAsync(key, field);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "Redis Hash删除字段失败,Key: {Key}, Field: {Field}", key, field);
|
||
throw;
|
||
}
|
||
}
|
||
}
|
||
}
|