311 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C#
		
	
	
	
			
		
		
	
	
			311 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C#
		
	
	
	
using Newtonsoft.Json;
 | 
						|
using StackExchange.Redis;
 | 
						|
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.Configuration;
 | 
						|
using System.Linq;
 | 
						|
using System.Web;
 | 
						|
 | 
						|
namespace WebAPI.Common
 | 
						|
{
 | 
						|
    /// <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);
 | 
						|
        }
 | 
						|
    }
 | 
						|
} |