0. What is Redis
Redis is an open source, with the ANSI C language, support network, can be based on memory can also be persistent log-type, Key-value database, and provide a variety of language APIs
1. Compare with other user state save scheme
General development of user status using session or cookie, two ways of the pros and cons.
Session: Easy to lose in InProc mode and cause concurrency problems. If you use SQL Server or SQL Server mode and you consume performance
Cookies are easy to expose some user information, plus decryption also consumes performance.
Redis adopted such a scheme to solve a few problems,
①.redis access speed is fast.
②. User data is not easily lost.
③. It is easy to support clusters with many users.
④. Ability to view online users.
⑤. Able to achieve a user login. (implemented by code, subsequent introduction)
⑥. Supports persistence. (Of course it may be useless)
2. Realize the idea
1. We know that the session is actually saved a sessionid in the cookie, the user will sessionid to the server every visit, the server through the ID to find the user's corresponding status data.
Here my way is also to define a SessionID in the cookie, the program needs to obtain the user state when the SessionID as the key in Redis to find.
2. At the same time session support the user will not be accessed at certain times to be recycled.
This feature is supported by the use of the keys in Redis to support expiration, but in terms of renewal it is necessary for the program to intercept requests to call this method (demo example)
The following start code explains
3.Redis Calling Interface
The Servicestack related DLL is referenced first.
Add the configuration in Web.config, which is used to set the Redis invocation address to be separated by "," for each service. The host is written in the first place
<appSettings>
<!--, split between each redis. The first must be a host-->
<add key= "Sessionredis" value= " 127.0.0.1:6384,127.0.0.1:6384 "/>
</appSettings>
Initialize configuration
Static managers ()
{
string sessionredis= configurationmanager.appsettings["Sessionredis"];
String timeOut = configurationmanager.appsettings["Sessionredistimeout"];
if (string. IsNullOrEmpty (Sessionredis))
{
throw new Exception ("Web.config missing configuration Sessionredis, split between each redis. 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,//number of "write" link pool links
maxreadpoolsize = writereadcount,//"read" Link pool links number
AutoStart = True
});
In order to control the convenience of writing a delegate
<summary>
///Write
///</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 write exception. Host:" + client. Host + ", Port:" + client. Port);
Finally
{
if (client!= null)
{
client. Dispose ();
}}}
A call to the example of the other specific look at the source
<summary>
///key/value Storage of objects to cache
///</summary>
///<typeparam name= "T" > Object category </typeparam>
///<param name= "value" > set 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. Implementation session
Write a SessionID to the cookie as described above
<summary>
///User status Management
///</summary> Public
class session
{
///<summary>
///initializes
///</summary>
///<param name= "_context" ></param> Public Sessions
( 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;
}
}
}
Ways to access the user
<summary>
///Get current user information
///</summary>
///<typeparam name= "T" ></typeparam>
///<returns></returns> Public
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" ></typeparam>
///<param name= "obj" ></param> public
void login<t> (T obj) where t:class,new ()
{ C24/>new redisclient<t> (). Kset (SessionId, obj, new TimeSpan (0, managers.timeout, 0));
6. Renewal
The default user does not have access to log off the user's logon status for more than 30 minutes, so the user's logoff time is postponed by 30 minutes per visit
This requires invoking the Redis renewal method
<summary>
///extension
///</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);
}
After encapsulation
///<summary>
///renewal
///</summary> public
Void Postpone ()
{
New Redisclient<object> (). Ksetentryin (SessionId, New TimeSpan (0, managers.timeout, 0));
}
Here I took advantage of the Actionfilter in MVC3 to intercept all requests from the user
Namespace Test
{public
class Sessionfilterattribute:actionfilterattribute
{
///<summary>
///Renew each request
///</summary>
///<param name= "Filtercontext" ></param>
Public override void OnActionExecuting (ActionExecutingContext filtercontext)
{
New session ( Filtercontext.httpcontext). Postpone ();}}
To register in the Global.asax
public static void Registerglobalfilters (Globalfiltercollection filters)
{
filters. ADD (New Sessionfilterattribute ());
}
protected void Application_Start ()
{
registerglobalfilters (globalfilters.filters);
}
5. Calling mode
To facilitate the invocation of the new feature in borrow 4.0, add controller to an extended attribute
public static class Extsessions
{public static sessions Sessionext (this Controller Controller)
{return
new Session (Controller. HttpContext);
}
Call method
public class Homecontroller:controller
{public
actionresult Index ()
{this
. Sessionext (). IsLogin ();
return View ();
}
6. Code Download
Click to download
7. Follow-up
SessionManager contains the number of user lists, log off a user, obtain user information based on user ID, Online user object list, online user SessionID list, and other methods
The following will implement a user login function
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.