天天看點

C# redis用戶端幫助類

需要在NuGet裡面引用ServiceStack.Redis

using ServiceStack.Redis;
using ServiceStack.Redis.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleRedisTest
{
    /// <summary>
    /// 需要在AppSettings裡面配置redis連接字元串節點,名稱固定為“redisHost”
    /// 例如,格式參考 value="server=192.168.31.42;port=6380;password=pisenmaster;db=9" 
    /// </summary>
    public class RedisTool : IDisposable
    {

        /// <summary>
        /// redis主機ip
        /// </summary>
        private readonly static string RedisServerIP = string.Empty;// "192.168.31.42";
        /// <summary>
        /// 連接端口
        /// </summary>
        private readonly static int RedisPort = 0;// 6380;
        /// <summary>
        /// 連接密碼
        /// </summary>
        private readonly static string RedisConnectPassword = string.Empty;// "pisenmaster";
        /// <summary>
        /// 緩沖池 實例db
        /// </summary>
        private readonly static string PooledRedisDB1 = string.Empty;// "[email protected]:6380";

        //預設緩存過期時間機關秒
        public const int secondsTimeOut = 60 * 60;

        /// <summary>
        ///  //加載配置檔案
        /// </summary>
        static RedisTool()
        {
            string conStr = System.Configuration.ConfigurationManager.AppSettings["redisHost"];
            try
            {
                if (string.IsNullOrWhiteSpace(conStr))
                {
                    throw new Exception("讀取配置檔案出錯,AppSettings節沒有配置名為redisHost的redis連接字元串");
                }
                string[] arr = conStr.Split(';');
                RedisServerIP = arr.First(w => w.ToLower().Contains("server="))?.Split('=')[1];
                RedisPort = Convert.ToInt32(arr.First(w => w.ToLower().Contains("port="))?.Split('=')[1]);
                RedisConnectPassword = arr.First(w => w.ToLower().Contains("password="))?.Split('=')[1];
                PooledRedisDB1 = $"{RedisConnectPassword}@{RedisServerIP}:{RedisPort}";
            }
            catch (Exception ex)
            {
                throw new Exception("讀取配置檔案出錯,AppSettings節裡面沒有配置redis連接字元串名為redisHost的節");
            }
        }

        /// <summary>
        /// redis客戶端
        /// </summary>
        public RedisClient Redis = new RedisClient(RedisServerIP, RedisPort, RedisConnectPassword, 9);
        //public RedisClient Redis = new RedisClient("192.168.31.42", 6380, "pisenmaster", 9);

        //緩存池
        private PooledRedisClientManager prcm = new PooledRedisClientManager();

        /// <summary>
        /// 構造函數
        /// </summary>
        /// <param name="OpenPooledRedis">是否開啟緩沖池</param>
        public RedisTool(bool OpenPooledRedis = false)
        {
            if (OpenPooledRedis)
            {
                //prcm = CreateManager(new[] { "[email protected]:6380" }, new[] { "[email protected]:6380" });
                prcm = CreateManager(new[] { PooledRedisDB1 }, new[] { PooledRedisDB1 });
                Redis = prcm.GetClient() as RedisClient;
            }
        }

        #region Key/Value存儲

        /// <summary>
        /// 設定緩存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">緩存建</param>
        /// <param name="t">緩存值</param>
        /// <param name="timeout">過期時間,機關秒,-1:不過期,0:預設過期時間</param>
        /// <returns></returns>
        public bool Set<T>(string key, T t, int timeout = 0)
        {
            if (timeout < 0)
            {
                //永不過期
                return Redis.Set(key, t);
            }
            if (timeout == 0)
            {
                //默認時長
                timeout = secondsTimeOut;
            }
            return Redis.Set(key, t, TimeSpan.FromSeconds(timeout));
        }

        /// <summary>
        /// 擷取
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public T Get<T>(string key)
        {
            return Redis.Get<T>(key);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool Remove(string key)
        {
            return Redis.Remove(key);
        }

        public bool Add<T>(string key, T t, int timeout)
        {
            if (timeout < 0)
            {
                //永不過期
                return Redis.Set(key, t);
            }
            if (timeout == 0)
            {
                //默認時長
                timeout = secondsTimeOut;
            }
            return Redis.Add(key, t, TimeSpan.FromSeconds(timeout));
        }

        #endregion

        #region 連結清單操作

        /// <summary>
        /// 根據IEnumerable資料添加連結清單
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="listId"></param>
        /// <param name="values"></param>
        /// <param name="timeout"></param>
        public void AddList<T>(string listId, IEnumerable<T> values, int timeout = 0)
        {
            IRedisTypedClient<T> iredisClient = Redis.As<T>();
            IRedisList<T> redisList = iredisClient.Lists[listId];
            redisList.AddRange(values);
            if (timeout >= 0)
            {
                if (timeout == 0)
                {
                    timeout = secondsTimeOut;
                }
                Redis.ExpireEntryIn(listId, TimeSpan.FromSeconds(timeout));
            }
            iredisClient.Save();
        }

        /// <summary>
        /// 添加單個實體到連結清單中
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="listId"></param>
        /// <param name="Item"></param>
        /// <param name="timeout">過期時間會覆蓋清單之前的過期時間,為-1時保持先前的過期設置</param>
        public void AddEntityToList<T>(string listId, T Item, int timeout = 0)
        {
            IRedisTypedClient<T> iredisClient = Redis.As<T>();
            IRedisList<T> redisList = iredisClient.Lists[listId];
            redisList.Add(Item);
            if (timeout >= 0)
            {
                if (timeout == 0)
                {
                    timeout = secondsTimeOut;
                }
                Redis.ExpireEntryIn(listId, TimeSpan.FromSeconds(timeout));
            }
            iredisClient.Save();
        }

        /// <summary>
        /// 擷取連結清單
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="listId"></param>
        /// <returns></returns>
        public IEnumerable<T> GetList<T>(string listId)
        {
            IRedisTypedClient<T> iredisClient = Redis.As<T>();
            return iredisClient.Lists[listId];
        }

        /// <summary>
        /// 在連結清單中删除單個實體
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="listId"></param>
        /// <param name="t"></param>
        public void RemoveEntityFromList<T>(string listId, T t)
        {
            IRedisTypedClient<T> iredisClient = Redis.As<T>();
            IRedisList<T> redisList = iredisClient.Lists[listId];
            redisList.RemoveValue(t);
            iredisClient.Save();
        }

        /// <summary>
        /// 根據lambada表達式删除符合條件的實體
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="listId"></param>
        /// <param name="func"></param>
        public void RemoveEntityFromList<T>(string listId, Func<T, bool> func)
        {
            IRedisTypedClient<T> iredisClient = Redis.As<T>();
            IRedisList<T> redisList = iredisClient.Lists[listId];
            T value = redisList.Where(func).FirstOrDefault();
            redisList.RemoveValue(value);
            iredisClient.Save();
        }

        #endregion

        #region 清空Redis所有資料庫中的所有key
        public void Flushall()
        {
            Redis.FlushAll();
        }
        #endregion

        //釋放資源
        public void Dispose()
        {
            if (Redis != null)
            {
                Redis.Dispose();
                Redis = null;
            }
            GC.Collect();
        }

        /// <summary>
        /// 緩沖池
        /// </summary>
        /// <param name="readWriteHosts"></param>
        /// <param name="readOnlyHosts"></param>
        /// <returns></returns>
        public static PooledRedisClientManager CreateManager(
        string[] readWriteHosts, string[] readOnlyHosts)
        {
            return new PooledRedisClientManager(readWriteHosts, readOnlyHosts,
            new RedisClientManagerConfig
            {
                MaxWritePoolSize = readWriteHosts.Length * 5,
                MaxReadPoolSize = readOnlyHosts.Length * 5,
                AutoStart = true,
            });
            // { RedisClientFactory = (IRedisClientFactory)RedisCacheClientFactory.Instance.CreateRedisClient("127.0.0.1", 6379) }; 
        }
    }

}