To realize the session function with Redis _redis

Source: Internet
Author: User
Tags httpcontext redis sessions static class

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.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.