久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

怎么使用redis實現session功能

140次閱讀
沒有評論

共計 4965 個字符,預計需要花費 13 分鐘才能閱讀完成。

自動寫代碼機器人,免費開通

這篇文章主要介紹怎么使用 redis 實現 session 功能,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

我們來簡單介紹下 redis。

Redis(Remote Dictionary Server ),即遠程字典服務,是一個開源的使用 ANSI C 語言編寫、支持網絡、可基于內存亦可持久化的日志型、Key-Value 數據庫,并提供多種語言的 API。從 2010 年 3 月 15 日起,Redis 的開發工作由 VMware 主持。從 2013 年 5 月開始,Redis 的開發由 Pivotal 贊助。

1. 與其他用戶狀態保存方案比較

一般開發中用戶狀態使用 session 或者 cookie,兩種方式各種利弊。

Session: 在 InProc 模式下容易丟失,并且引起并發問題。如果使用 SQLServer 或者 SQLServer 模式又消耗了性能

Cookie 則容易將一些用戶信息暴露,加解密同樣也消耗了性能。

Redis 采用這樣的方案解決了幾個問題,

1.Redis 存取速度快。

2. 用戶數據不容易丟失。

3. 用戶多的情況下容易支持集群。

4. 能夠查看在線用戶。

5. 能夠實現用戶一處登錄。(通過代碼實現,后續介紹)

6. 支持持久化。(當然可能沒什么用)

2. 實現思路

1. 我們知道 session 其實是在 cookie 中保存了一個 sessionid,用戶每次訪問都將 sessionid 發給服務器,服務器通過 ID 查找用戶對應的狀態數據。

在這里我的處理方式也是在 cookie 中定義一個 sessionid,程序需要取得用戶狀態時將 sessionid 做為 key 在 Redis 中查找。

2. 同時 session 支持用戶在一定時間不訪問將 session 回收。

借用 Redis 中 Keys 支持過期時間的特性支持這個功能,但是在續期方面需要程序自行攔截請求調用這個方法(demo 有例子)

下面開始代碼說明

3.Redis 調用接口

首先引用 ServiceStack 相關 DLL。

在 web.config 添加配置,這個配置用來設置 Redis 調用地址每臺服務用【,】隔開。主機寫在第一位

appSettings 
  !-- 每臺 Redis 之間用, 分割. 第一個必須為主機 -- 
  add key= SessionRedis  value= 127.0.0.1:6384,127.0.0.1:6384 / 
 /appSettings

初始化配置

static Managers()
 {
 string sessionRedis= ConfigurationManager.AppSettings[ SessionRedis 
 string timeOut = ConfigurationManager.AppSettings[ SessionRedisTimeOut 
 if (string.IsNullOrEmpty(sessionRedis))
 {
 throw new Exception( web.config  缺少配置 SessionRedis, 每臺 Redis 之間用, 分割. 第一個必須為主機 
 }
 if (string.IsNullOrEmpty(timeOut)==false)
 { TimeOut = Convert.ToInt32(timeOut);
 }
 var host = sessionRedis.Split(char.Parse( ,));
 var writeHost = new string[] { host[0] };
 var readHosts = host.Skip(1).ToArray();
 ClientManagers = new PooledRedisClientManager(writeHost, readHosts, new RedisClientManagerConfig
 {
 MaxWritePoolSize = writeReadCount,//“寫”鏈接池鏈接數
 MaxReadPoolSize = writeReadCount,//“讀”鏈接池鏈接數
 AutoStart = true
 });
 }

為了控制方面寫了一個委托

///  summary 
 ///  寫入
 ///  /summary 
 ///  typeparam name= F /typeparam 
 ///  param name= doWrite /param 
 ///  returns /returns 
 public F TryRedisWrite F (Func IRedisClient, F  doWrite)
 { PooledRedisClientManager prcm = new Managers().GetClientManagers();
 IRedisClient client = null;
 try
 { using (client = prcm.GetClient())
 { return doWrite(client);
 }
 }
 catch (RedisException)
 { throw new Exception( Redis 寫入異常.Host:  + client.Host +  ,Port:  + client.Port);
 }
 finally
 { if (client != null)
 { client.Dispose();
 }
 }
 }

一個調用的例子其他的具體看源碼

///  summary 
 ///  以 Key/Value 的形式存儲對象到緩存中
 ///  /summary 
 ///  typeparam name= T 對象類別 /typeparam 
 ///  param name= value 要寫入的集合 /param 
 public void KSet(Dictionary string, T  value)
 { Func IRedisClient, bool  fun = (IRedisClient client) = 
 { client.SetAll T (value);
 return true;
 };
 TryRedisWrite(fun);
 }

4. 實現 Session

按上面說的給 cookie 寫一個 sessionid

///  summary 
 ///  用戶狀態管理
 ///  /summary 
 public class Session
 {
 ///  summary 
 ///  初始化
 ///  /summary 
 ///  param name= _context /param 
 public Session(HttpContextBase _context)
 {
 var context = _context;
 var cookie = context.Request.Cookies.Get(SessionName);
 if (cookie == null || string.IsNullOrEmpty(cookie.Value))
 { SessionId = NewGuid();
 context.Response.Cookies.Add(new HttpCookie(SessionName, SessionId));
 context.Request.Cookies.Add(new HttpCookie(SessionName, SessionId));
 }
 else
 {
 SessionId = cookie.Value;
 }
 }
 }

去存取用戶的方法

///  summary 
 ///  獲取當前用戶信息
 ///  /summary 
 ///  typeparam name= T /typeparam 
 ///  returns /returns 
 public object Get T () where T:class,new()
 { return new RedisClient T ().KGet(SessionId);
 }
 ///  summary 
 ///  用戶是否在線
 ///  /summary 
 ///  returns /returns 
 public bool IsLogin()
 { return new RedisClient object ().KIsExist(SessionId);
 }
 ///  summary 
 ///  登錄
 ///  /summary 
 ///  typeparam name= T /typeparam 
 ///  param name= obj /param 
 public void Login T (T obj) where T : class,new()
 { new RedisClient T ().KSet(SessionId, obj, new TimeSpan(0, Managers.TimeOut, 0));
 }

6. 續期

默認用戶沒訪問超過 30 分鐘注銷用戶的登錄狀態,所以用戶每次訪問都要將用戶的注銷時間推遲 30 分鐘

這需要調用 Redis 的續期方法

///  summary 
 ///  延期
 ///  /summary 
 ///  param name= key /param 
 ///  param name= expiresTime /param 
 public void KSetEntryIn(string key, TimeSpan expiresTime)
 { Func IRedisClient, bool  fun = (IRedisClient client) = 
 { client.ExpireEntryIn(key, expiresTime);
 return false;
 };
 TryRedisWrite(fun);
 }

封裝以后

///  summary 
///  續期
///  /summary 
public void Postpone()
new RedisClient object ().KSetEntryIn(SessionId, new TimeSpan(0, Managers.TimeOut, 0));
}

這里我利用了 MVC3 中的 ActionFilter,攔截用戶的所有請求

namespace Test
 public class SessionFilterAttribute : ActionFilterAttribute
 {
 ///  summary 
 ///  每次請求都續期
 ///  /summary 
 ///  param name= filterContext /param 
 public override void OnActionExecuting(ActionExecutingContext filterContext)
 { new Session(filterContext.HttpContext).Postpone();
 }
 }
}

在 Global.asax 中要注冊一下

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
 { filters.Add(new SessionFilterAttribute());
 }
 protected void Application_Start()
 { RegisterGlobalFilters(GlobalFilters.Filters);
 }

5. 調用方式

為了方便調用借用 4.0 中的新特性,把 Controller 添加一個擴展屬性

public static class ExtSessions
{public static Session SessionExt(this Controller controller)
 { return new Session(controller.HttpContext);
 }
}

調用方法:

public class HomeController : Controller
 { public ActionResult Index()
 { this.SessionExt().IsLogin();
 return View();
 }
 }

以上是“怎么使用 redis 實現 session 功能”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注丸趣 TV 行業資訊頻道!

向 AI 問一下細節

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-12-04發表,共計4965字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 来宾市| 四子王旗| 屯留县| 南澳县| 灯塔市| 龙州县| 乐业县| 衡南县| 淮阳县| 延寿县| 大同县| 雷波县| 阳曲县| 周至县| 安陆市| 栾城县| 郁南县| 无极县| 嘉禾县| 时尚| 会昌县| 阿勒泰市| 鹤岗市| 济宁市| 修文县| 广灵县| 出国| 七台河市| 云和县| 南安市| 平阴县| 淄博市| 宁都县| 丰镇市| 垣曲县| 温宿县| 双牌县| 塘沽区| 阿克苏市| 溆浦县| 论坛|