1. 程式人生 > 實用技巧 >Redis實戰與 Session快取

Redis實戰與 Session快取

C#操作Redis的庫有很多,比如C# Redis Client就很好用,

在NuGet上搜索ServiceStack.Redis

安裝到專案中,將會新增以下引用

ServiceStack.Redis 庫為我們提供了RedisClient類,其繼承了IDisposable介面,所以可用using塊來代替try-catch-finally.

Redis有幾種常用的資料型別:

  1.String

  2.Hash(Hash表)

  3.List(雙向連結串列)

  4.Set(集合型別)

  5.Sortedset

RedisClient中常用的方法

方法 說明
Add 根據傳入的key-value新增一條記錄,當key已存在返回false
FlushAll 使所有快取失效(清除Redis所有資料庫的所有Key)
Get 根據傳入的key獲取一條記錄的值
GetAll 根據傳入的多個key獲取多條記錄的值
Remove 根據傳入的key移除一條記錄
RemoveAll 根據傳入的多個key移除多條記錄
Replace 根據傳入的key覆蓋一條記錄的值,當key不存在不會新增
Set 根據傳入的key修改一條記錄的值,當key不存在則新增
SetAll 根據傳入的多個key覆蓋多條記錄
Increment
Decrement

針對實體物件的儲存,RedisClient提供了

  public bool Set<T>(string key, T value);
  public bool Set<T>(string key, T value, TimeSpan expiresIn);
  public bool Set<T>(string key, T value, DateTime expiresAt);

  public T Get<T>(string key);

泛型方法,可以方便的儲存實體物件。

針對某些事務,RedisClient提供了:

方法 說明
AcquireLock 申請對一個Key加鎖(期間其他物件不能訪問)
CreateTransaction 建立一個事務,返回一個IRedisTransaction物件
CreateSubscription 建立一個訂閱事件返回一個IRedisSubscription物件
CreatePipeline 返回一個IRedisPipeline物件

下面我們寫一個簡單Redis操作的幫助類 命名為RedisHelper,為SessionHelper做準備.

  其中_ip = "127.0.0.1"表示本機回傳地址,_port = 6379為Redis服務埠.

  public class RedisHelper : IRedisHelper
    {
        private readonly string _ip = "127.0.0.1";
        private readonly int _port = 6379;
        private readonly string _passWord = string.Empty;
        public int Expire { get; set; }

        public RedisHelper(int expireTime=1200)
        {
            Expire = expireTime;
        }

        public RedisHelper(string ip, int port, string passWord, int expireTime=1200)
        {
            _ip = ip;
            _port = port;
            _passWord = passWord;
            Expire = expireTime;
        }

        public T GetValue<T>(string key)
        {
            using (var redisClient = GetRedisClient())
            {
                return redisClient.Get<T>(key);
            }
        }

        public bool SetValue(string key,string value)
        {
            using (var redisClient = GetRedisClient())
            {
                if (!redisClient.Set(key, value)) return false;
                SetExpire(redisClient, key);
                return true;
            }
        }

        public void SetValue<T>(string key,T value)
        {
            using (var redisClient = GetRedisClient())
            {
                if (redisClient.Set<T>(key, value)) 
                    SetExpire(redisClient, key);
            }
        }

        public void Delete(string key)
        {
            using (var redisClient = GetRedisClient())
            {
                redisClient.Remove(key);
            }
        }

        private RedisClient GetRedisClient()
        {
            return new RedisClient(_ip, _port, _passWord);
        }

        private void SetExpire(IRedisNativeClient redisClient,string key)
        {
            redisClient.Expire(key, Expire);
        }
    }

  

有了RedisHelper 我們再來寫一個管理Session的類:

    public class SessionHelper<T>:RedisHelper, ISessionHelper<T>
    {
        public T GetSession(string token)
        {
            return !string.IsNullOrEmpty(token) ? GetValue<T>(token) : default(T);
        }

        public string CreateSession(T value)
        {
            var guid = Guid.NewGuid().ToString("D");
            SetValue<T>(guid,value);
            
            return guid;
        }

        public void RemoveSession(string token)
        {
            Delete(token);
        }
    }

至此 我們在Controller中寫一個Login方法來測試一下。

   public ActionResult Login()
        {
            //登入邏輯
            var userLoginInfo = new UserSession
            {
                Id = 12,
                Name = "Test",
                Permissions = new List<string>{"Home.page"}
            };

            var token = _sessionHelper.CreateSession(userLoginInfo);

            var cookie = new HttpCookie("User")
            {
                Expires = DateTime.Now.AddMinutes(20),
                Value = token
            };

            Response.AppendCookie(cookie);

            return View();
        }

這就是 Cookie+快取 實現一套最基本的會話管理機制。