308 lines
9.8 KiB
C#
308 lines
9.8 KiB
C#
|
using System;
|
|||
|
using System.Configuration;
|
|||
|
using Newtonsoft.Json;
|
|||
|
using StackExchange.Redis;
|
|||
|
|
|||
|
namespace BLL
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public class Redis : ICache
|
|||
|
{
|
|||
|
int Default_Timeout = 600;//默认超时时间(单位秒)
|
|||
|
string address;
|
|||
|
JsonSerializerSettings jsonConfig = new JsonSerializerSettings() { ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore, NullValueHandling = NullValueHandling.Ignore };
|
|||
|
ConnectionMultiplexer connectionMultiplexer;
|
|||
|
IDatabase database;
|
|||
|
|
|||
|
class CacheObject<T>
|
|||
|
{
|
|||
|
public int ExpireTime { get; set; }
|
|||
|
public bool ForceOutofDate { get; set; }
|
|||
|
public T Value { get; set; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// <param name="dbbase"></param>
|
|||
|
public Redis(int dbbase = 0)
|
|||
|
{
|
|||
|
this.address = this.address = ConfigurationManager.AppSettings["RedisHosts"];
|
|||
|
|
|||
|
if (this.address == null || string.IsNullOrWhiteSpace(this.address.ToString()))
|
|||
|
throw new ApplicationException("配置文件中未找到RedisServer的有效配置");
|
|||
|
connectionMultiplexer = ConnectionMultiplexer.Connect(address);
|
|||
|
database = connectionMultiplexer.GetDatabase(dbbase);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 连接超时设置
|
|||
|
/// </summary>
|
|||
|
public int TimeOut
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return Default_Timeout;
|
|||
|
}
|
|||
|
set
|
|||
|
{
|
|||
|
Default_Timeout = value;
|
|||
|
}
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// <param name="key"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public object Get(string key)
|
|||
|
{
|
|||
|
return Get<object>(key);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// <typeparam name="T"></typeparam>
|
|||
|
/// <param name="key"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public T Get<T>(string key)
|
|||
|
{
|
|||
|
|
|||
|
DateTime begin = DateTime.Now;
|
|||
|
var cacheValue = database.StringGet(key);
|
|||
|
DateTime endCache = DateTime.Now;
|
|||
|
var value = default(T);
|
|||
|
if (!cacheValue.IsNull)
|
|||
|
{
|
|||
|
var cacheObject = JsonConvert.DeserializeObject<CacheObject<T>>(cacheValue, jsonConfig);
|
|||
|
if (!cacheObject.ForceOutofDate)
|
|||
|
database.KeyExpire(key, new TimeSpan(0, 0, cacheObject.ExpireTime));
|
|||
|
value = cacheObject.Value;
|
|||
|
}
|
|||
|
DateTime endJson = DateTime.Now;
|
|||
|
return value;
|
|||
|
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// <param name="key"></param>
|
|||
|
/// <param name="data"></param>
|
|||
|
public void Insert(string key, object data)
|
|||
|
{
|
|||
|
var jsonData = GetJsonData(data, TimeOut, false);
|
|||
|
database.StringSet(key, jsonData);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// <param name="key"></param>
|
|||
|
/// <param name="data"></param>
|
|||
|
/// <param name="cacheTime"></param>
|
|||
|
public void Insert(string key, object data, int cacheTime)
|
|||
|
{
|
|||
|
var timeSpan = TimeSpan.FromSeconds(cacheTime);
|
|||
|
var jsonData = GetJsonData(data, TimeOut, true);
|
|||
|
database.StringSet(key, jsonData, timeSpan);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// <param name="key"></param>
|
|||
|
/// <param name="data"></param>
|
|||
|
/// <param name="cacheTime"></param>
|
|||
|
public void Insert(string key, object data, DateTime cacheTime)
|
|||
|
{
|
|||
|
var timeSpan = cacheTime - DateTime.Now;
|
|||
|
var jsonData = GetJsonData(data, TimeOut, true);
|
|||
|
database.StringSet(key, jsonData, timeSpan);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// <typeparam name="T"></typeparam>
|
|||
|
/// <param name="key"></param>
|
|||
|
/// <param name="data"></param>
|
|||
|
public void Insert<T>(string key, T data)
|
|||
|
{
|
|||
|
var jsonData = GetJsonData<T>(data, TimeOut, false);
|
|||
|
database.StringSet(key, jsonData);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// <typeparam name="T"></typeparam>
|
|||
|
/// <param name="key"></param>
|
|||
|
/// <param name="data"></param>
|
|||
|
/// <param name="cacheTime"></param>
|
|||
|
public void Insert<T>(string key, T data, int cacheTime)
|
|||
|
{
|
|||
|
var timeSpan = TimeSpan.FromSeconds(cacheTime);
|
|||
|
var jsonData = GetJsonData<T>(data, TimeOut, true);
|
|||
|
database.StringSet(key, jsonData, timeSpan);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// <typeparam name="T"></typeparam>
|
|||
|
/// <param name="key"></param>
|
|||
|
/// <param name="data"></param>
|
|||
|
/// <param name="cacheTime"></param>
|
|||
|
public void Insert<T>(string key, T data, DateTime cacheTime)
|
|||
|
{
|
|||
|
var timeSpan = cacheTime - DateTime.Now;
|
|||
|
var jsonData = GetJsonData<T>(data, TimeOut, true);
|
|||
|
database.StringSet(key, jsonData, timeSpan);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// <param name="data"></param>
|
|||
|
/// <param name="cacheTime"></param>
|
|||
|
/// <param name="forceOutOfDate"></param>
|
|||
|
/// <returns></returns>
|
|||
|
string GetJsonData(object data, int cacheTime, bool forceOutOfDate)
|
|||
|
{
|
|||
|
var cacheObject = new CacheObject<object>() { Value = data, ExpireTime = cacheTime, ForceOutofDate = forceOutOfDate };
|
|||
|
return JsonConvert.SerializeObject(cacheObject, jsonConfig);//序列化对象
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// <typeparam name="T"></typeparam>
|
|||
|
/// <param name="data"></param>
|
|||
|
/// <param name="cacheTime"></param>
|
|||
|
/// <param name="forceOutOfDate"></param>
|
|||
|
/// <returns></returns>
|
|||
|
string GetJsonData<T>(T data, int cacheTime, bool forceOutOfDate)
|
|||
|
{
|
|||
|
var cacheObject = new CacheObject<T>() { Value = data, ExpireTime = cacheTime, ForceOutofDate = forceOutOfDate };
|
|||
|
return JsonConvert.SerializeObject(cacheObject, jsonConfig);//序列化对象
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// 删除
|
|||
|
/// </summary>
|
|||
|
/// <param name="key"></param>
|
|||
|
public void Remove(string key)
|
|||
|
{
|
|||
|
database.KeyDelete(key, CommandFlags.HighPriority);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 判断key是否存在
|
|||
|
/// </summary>
|
|||
|
public bool Exists(string key)
|
|||
|
{
|
|||
|
return database.KeyExists(key);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 右侧入队
|
|||
|
/// </summary>
|
|||
|
/// <param name="queueName">队列名称</param>
|
|||
|
/// <param name="redisValue">值</param>
|
|||
|
/// <returns></returns>
|
|||
|
public long EnqueueListRightPush(RedisKey queueName, RedisValue redisValue)
|
|||
|
{
|
|||
|
return database.ListRightPush(queueName, redisValue);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 左侧入队
|
|||
|
/// </summary>
|
|||
|
/// <param name="queueName">队列名称</param>
|
|||
|
/// <param name="redisvalue">队列值</param>
|
|||
|
/// <returns></returns>
|
|||
|
public long EnqueueListLeftPush(RedisKey queueName, RedisValue redisvalue)
|
|||
|
{
|
|||
|
return database.ListLeftPush(queueName, redisvalue);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 获取队列长度
|
|||
|
/// </summary>
|
|||
|
/// <param name="queueName">队列名称</param>
|
|||
|
/// <returns></returns>
|
|||
|
public long EnqueueListLength(RedisKey queueName)
|
|||
|
{
|
|||
|
if (database.KeyExists(queueName))
|
|||
|
{
|
|||
|
return database.ListLength(queueName);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 左侧出队
|
|||
|
/// </summary>
|
|||
|
/// <param name="queueName"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public string DequeueListPopLeft(RedisKey queueName)
|
|||
|
{
|
|||
|
int count = database.ListRange(queueName).Length;
|
|||
|
if (count > 0)
|
|||
|
{
|
|||
|
string redisValue = database.ListLeftPop(queueName);
|
|||
|
if (!string.IsNullOrEmpty(redisValue))
|
|||
|
return redisValue;
|
|||
|
else
|
|||
|
return string.Empty;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return "-1";
|
|||
|
throw new Exception($"队列{queueName}数据为零");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 右侧出队
|
|||
|
/// </summary>
|
|||
|
public string DequeueListPopRight(RedisKey queueName)
|
|||
|
{
|
|||
|
int count = database.ListRange(queueName).Length;
|
|||
|
if (count > 0)
|
|||
|
{
|
|||
|
string redisValue = database.ListRightPop(queueName);
|
|||
|
if (!string.IsNullOrEmpty(redisValue))
|
|||
|
return redisValue;
|
|||
|
else
|
|||
|
return string.Empty;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return "-1";
|
|||
|
throw new Exception($"队列{queueName}数据为零");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 分布式加锁
|
|||
|
/// </summary>
|
|||
|
/// <param name="key">键</param>
|
|||
|
/// <param name="data">值</param>
|
|||
|
/// <param name="seconds">过期时间</param>
|
|||
|
/// <returns></returns>
|
|||
|
public bool LockTake(string key, string data, TimeSpan seconds, int db = 0)
|
|||
|
{
|
|||
|
return database.LockTake(key, data, seconds);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 解锁
|
|||
|
/// </summary>
|
|||
|
/// <param name="key">键</param>
|
|||
|
/// <param name="data">值</param>
|
|||
|
/// <returns></returns>
|
|||
|
public bool LockRelease(string key, string data, int db = -1)
|
|||
|
{
|
|||
|
return database.LockRelease(key, data);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|