文章出處

一、簡介

Redis是著名的NOSQL數據庫,本質就是存儲鍵值對結構的數據,為存儲鍵值對數據做了優化,在大型網站中應用很多。Redis提供了數據的自動過期處理,因此適合存儲臨時數據。

 和Redis類似的還有Memcached, Redis可以把數據持久化到硬盤中,而Memcached是放到內存中,重啟后就消失,一般用Memcached做緩存。

 


 

二、Redis服務器的部署(Windows)

Redis服務器有Linux、Windows版,Linux版性能好適合生產環境。這里只說明Windows里配置Redis服務器,用于開發。

 

1.安裝Redis服務

文件下載:redisbin_x32

安裝路徑不要包含中文或其他特殊符號,解壓后服務相關文件如下:

 

redis-server.exe單擊該文件雖然可以開啟服務,但是要一直保證這個文件不能關閉,雙擊點開如圖:

 

 

 

2.把Redis服務配置到Windows服務里

說明:配置此項后,不必去通過找到“redis-server.exe”文件單擊打開一直掛著,才能使用服務。

文件下載:RedisWatcher1

解壓安裝后相關文件如下:

 

修改“watcher.conf”文件里,打開文件,進行圖片說明的操作

 

 

修改后去Windows服務里開啟Redis服務,如圖:

 

 

 


 

 

三、在.net中操作Redis

 

1.在項目中導入相關的.dll文件的引用

文件下載:Redis.Net驅動

 相關.dll如圖:

 

 

 

2.創建一個RedisManage類

寫入以下關鍵代碼:

 1 using ServiceStack.Redis;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace Redis_Test
 9 {
10     class RedisManage
11     {
12 
13         public static PooledRedisClientManager ClientManager { get; private set; }
14         static RedisManage()
15         {
16             RedisClientManagerConfig redisConfig = new RedisClientManagerConfig();
17             redisConfig.MaxWritePoolSize = 128;
18             redisConfig.MaxReadPoolSize = 128;
19 
20             //可以讀寫分離,指定一臺服務器讀,一臺寫。
21             // new PooledRedisClientManage(讀寫的服務器地址,只讀的服務器地址
22             ClientManager = new PooledRedisClientManager(new string[] { "127.0.0.1" }, 
23                 new string[] {"127.0.0.1"}, redisConfig);
24         }
25 
26 
27     }
28 }
RedisManage

 

 

 

3.存儲信息的方法

 1 
 2             using (IRedisClient con = RedisManage.ClientManager.GetClient())
 3             {
 4                 //存數據
 5                 con.Set<int>("age", 18);
 6                 Dictionary<string, string> dic = new Dictionary<string, string>();
 7                 dic["yzk"] = "test";
 8                 con.Set<Dictionary<string, string>>("dic", dic);
 9 
10             }

 

 

 4.讀取數據

1  using (IRedisClient con = RedisManage.ClientManager.GetClient())
2             {
3                 //取數據
4                 int age = con.Get<int>("age");
5                 Console.WriteLine(age);
6                 Dictionary<string, string> dic = con.Get<Dictionary<string, string>>("dic");
7                 Console.WriteLine(dic["yzk"]);
8 
9             }

 

 

 

5. 支持寫入數據設置超時:

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

第三個參數DateTime,可以指定數據到期時間,到期數據將不存在服務器里

 

 

 


 

 

四、在項目解決的一些問題

1.同一個用戶名只能在一臺電腦或者一個瀏覽器中登陸,嚴格來說是一個Session,Web中很難區別是否是同一臺電腦,

 這里的本質是使用用戶名與SessionID進行鍵值對關聯,存儲到Redis中。

 

 

技術思路:在編寫用戶登陸代碼處,將用戶名(唯一)做為鍵,當前的SessionId作為值,存儲到Redis數據庫中。然后在每次請求頁面時,

就把當前SessionID取出,在把對應的Redis中的SessionId取出,兩者進行比較,假如這時用戶已經換了瀏覽器登陸,那么Redis中對應的SessionID將覆蓋了,

兩者不對等,那么就證明該用戶在其他地方進行了登陸。

 

 

俗語:但凡登陸就要用當前SessionID覆蓋Redis中的SessionID,只要每當請求,發現當前SessionIDRedis中的不同,該頁面就要清除登陸,清除Session,說明這個用戶去了其他位置登陸了。

 

代碼參考,登錄成功某處:

1   context.Session["user"] = model;
2             //用戶名與SessionId鍵值對關系存儲到Redis中
3             using (var con = RedisManage.ClientManager.GetClient())
4             {
5                 //存數據   
6                 con.Set<string>(model.username,context.Session.SessionID);
7 
8             }

 

 

 

由于,用戶每次請求頁面都要檢查,我將此操作配置到Global文件中

參考代碼:

 

 1 using Common;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Web;
 6 using System.Web.Security;
 7 using System.Web.SessionState;
 8 using Model;
 9 namespace rupeng
10 {
11     public class Global : System.Web.HttpApplication
12     {
13 
14         public override void Init()
15         {
16             base.Init();
17             //必須到Init()中監聽
18             //每個需要Seesion頁面啟動都會執行AcquireRequestState事件
19             //AcquireRequestState事件執行的時候Session已經準備好了
20             this.AcquireRequestState += Global_AcquireRequestState;
21         }
22 
23         void Global_AcquireRequestState(object sender, EventArgs e)
24         {
25             if (HttpContext.Current.Session==null)
26             {
27                 return;
28             }
29 
30           
31             if (Context.Session["user"]==null)   //排除用戶沒有登錄
32             {
33                 return;
34             }
35             user_guest model= Context.Session["user"] as user_guest;
36             using (var con = RedisManage.ClientManager.GetClient())
37             {
38                 string redis_sId = con.Get<string>(model.username);
39 
40                 //發現不對等,用戶在其他位置登陸了,銷毀當前Seesion
41                 if (redis_sId!=Context.Session.SessionID)
42                 {
43                     Context.Session.Clear();
44                     Context.Session.Abandon();
45                 }
46 
47             }
48 
49 
50         }
51 
52 
53         protected void Application_Start(object sender, EventArgs e)
54         {
55 
56         }
57 
58         protected void Session_Start(object sender, EventArgs e)
59         {
60 
61         }
62 
63         protected void Application_BeginRequest(object sender, EventArgs e)
64         {
65             
66         }
67 
68         protected void Application_AuthenticateRequest(object sender, EventArgs e)
69         {
70 
71         }
72 
73         protected void Application_Error(object sender, EventArgs e)
74         {
75 
76         }
77 
78         protected void Session_End(object sender, EventArgs e)
79         {
80 
81         }
82 
83         protected void Application_End(object sender, EventArgs e)
84         {
85 
86         }
87     }
88 }
Global

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()