0. What is Redis
Redis is an open source API that is written in ANSI C, supports the network, can be persisted in memory, key-value databases, and provides multiple languages.
---wikipedia
1. Compare to other user state save scenarios
session: Easy to lose in InProc mode and cause concurrency problems. If you use SQL Server or SQL Server mode and you consume performance
cookie is easy to expose some user information, and decryption also consumes performance.
Redis uses such a scheme to solve several problems,
1.Redis access speed is fast.
2. User data cannot be easily lost.
3. The cluster is easily supported by the user in many cases.
4. Ability to view online users.
5. Be able to implement a user login at one place. (implemented by code, followed by)
6. Support Persistence. (Of course it may not work)
2. Realization of Ideas
1. We know that the session is actually stored in a cookie SessionID, the user each access will be sessionid to the server, the server through the ID of the user to find the corresponding state data.
My handling here is also to define a SessionID in the cookie, the program needs to get the user state when the SessionID as key to find in Redis.
2. At the same time the session allows users to not access the session during a certain period to recycle.
This feature is supported by the use of the keys in Redis to support expiration, but it is required to invoke this method on the program's own interception request in the renewal phase (Demo has an example)
The following starts the code description
3.Redis Calling Interface
The Servicestack related DLLs are referenced first.
In the Web. config add configuration, this configuration is used to set the Redis invocation address for each service separated by ",". Host written in first place
1 <appSettings> 2 3 <!--for each Redis, split. First must be host--4 <add key= "Sessionredis" value= "12 7.0.0.1:6384,127.0.0.1:6384 "/> 5 6 </appSettings> Initialize configuration static Managers () { String sessionredis= configurationmanager.appsettings["Sessionredis"]; String timeOut = configurationmanager.appsettings["Sessionredistimeout"]; if (string. IsNullOrEmpty (Sessionredis)) {throw new Exception ("Web. config is missing configuration Sessionredis, each Redis Partition. The first must be a host "); } 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,//"write" link Pool link number Maxreadpoolsize = writereadcount,//"read" link pool link number AutoStart = true}); } for control convenience write a delegate///<summary>///write////</summary>//<typepa Ram 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 write exception. Host:" + client.) Host + ", Port:" + client. Port); } finally {if (client! = NULL) { Client. Dispose (); }}} An example of a call to other specific source///<summary>/////////To store objects in key/value form in the cache </summary>//<typeparam name= "T" > Object category </typeparam>//<param Nam E= "Value" > collection to write </param> public void Kset (dictionary<string, t> value) { Func<iredisclient, bool> fun = (iredisclient client) = = {Client. Setall<t> (value); return true; }; Tryrediswrite (fun); } 4. Implement the session as described above, write a sessionid to the cookie.//<summary>//user status Management/// Lt;/summary> public class Session {//<summary>//Initialize///</summary>//<param Nam E= "_context" ></param> public Session (HttpContextBase _context) {var context = _context; var cookie = context. Request.Cookies.Get (sessionname); if (cookie = = NULL | | string. IsNullOrEmpty (cookies. Value) {SessionId = NewGuid (); Context. RESPONSE.COOKIES.ADD (New HttpCookie (SessionName, SessionId)); Context. REQUEST.COOKIES.ADD (New HttpCookie (SessionName, SessionId)); } else {SessionId = cookie. Value; }}} to access the user's method//<summary>////Get current User information///</summary> <typeparam name= "T" ></typeparam>//<returns></returns> Pub Lic OBJect get<t> () where T:class,new () {return new redisclient<t> (). Kget (SESSIONID); }//<summary>//Users online//</summary>//<returns></ Returns> public bool IsLogin () {return new redisclient<object> (). Kisexist (SESSIONID); }//<summary>//Login///</summary>//<typeparam name= "T" &G t;</typeparam>//<param name= "obj" ></param> public void login<t> (T obj) wh Ere t:class,new () {new redisclient<t> (). Kset (SessionId, obj, new TimeSpan (0, managers.timeout, 0)); } 6. The default user does not have access to the logged on user for more than 30 minutes, so the user's logoff time will be postponed for 30 minutes per visit. This requires a call to Redis renewal method//<summary& Gt Extension//</summary>//<param name= "key";</param>//<param name= "expirestime" ></param> public void Ksetentryin (String ke Y, TimeSpan expirestime) {func<iredisclient, bool> fun = (iredisclient client) = {Client. Expireentryin (key, Expirestime); return false; }; Tryrediswrite (fun); } package after///<summary>//renewals///</summary> public void Postpone () {New redisclient& Lt;object> (). Ksetentryin (SessionId, New TimeSpan (0, managers.timeout, 0)); Here I use the actionfilter in MVC3 to intercept all requests namespace Test {public class Sessionfilterattribute:acti Onfilterattribute {//<summary>///Per request renewal///</summary> <param name= "Filtercontext" ></param> public override void OnActionExecuting (Actionexecutingco ntext FiltercontexT) {new Session (Filtercontext.httpcontext). Postpone (); }}} to register public static void Registerglobalfilters (Globalfiltercollection filters) in Global.asax {Filters. ADD (New Sessionfilterattribute ()); } protected void Application_Start () {registerglobalfilters (globalfilters.filters); 5. Call mode in order to facilitate the invocation of new features in borrowing 4.0, add the controller an extended property public static class Extsessions {Publi C Static Session Sessionext (this controller controller) {return new session (controller. HttpContext); }} Call method public class Homecontroller:controller {public ActionResult Index () {this. Sessionext (). IsLogin (); return View (); }} 6. Download downloads 7. Subsequent sessionmanager contains the number of user lists, logs off a user, obtains user information based on user ID, Online user object list, online user SessionID list, etc.Method
Storage session with Redis