Maison > base de données > Redis > le corps du texte

Comment utiliser Redis pour implémenter la fonction de session

王林
Libérer: 2021-02-22 09:26:04
avant
7961 Les gens l'ont consulté

Comment utiliser Redis pour implémenter la fonction de session

Présentons brièvement redis.

Redis (Remote Dictionary Server), le service de dictionnaire distant, est une base de données de valeurs-clés de type journal open source écrite en langage ANSI C, prend en charge le réseau, peut être basée sur la mémoire et persistante, et fournit plusieurs API de langage. Depuis le 15 mars 2010, le développement de Redis est hébergé par VMware. Depuis mai 2013, le développement de Redis est sponsorisé par Pivotal.

1. Comparaison avec d'autres solutions de sauvegarde de l'état utilisateur

Généralement en développement, l'état utilisateur utilise une session ou un cookie, les deux méthodes ont des avantages et des inconvénients différents.

Session : Il est facile de perdre en mode InProc et de provoquer des problèmes de concurrence. Si vous utilisez SQLServer ou le mode SQLServer et consommez des performances

Les cookies peuvent facilement exposer certaines informations utilisateur, et le cryptage et le déchiffrement consomment également des performances.

Redis utilise cette solution pour résoudre plusieurs problèmes,

1 Redis a une vitesse d'accès rapide.

2. Les données utilisateur ne sont pas facilement perdues.

3. Il est facile de prendre en charge des clusters lorsqu'il y a de nombreux utilisateurs.

4. Capable de visualiser les utilisateurs en ligne.

5. Capable de permettre aux utilisateurs de se connecter à un seul endroit. (Réalisé grâce au code, introduit plus tard)

6. Prise en charge de la persistance. (Bien sûr, cela peut être inutile)

2. Idées d'implémentation

1. Nous savons que la session enregistre en fait un identifiant de session dans un cookie. L'utilisateur envoie l'identifiant de session au serveur à chaque fois qu'il visite. , et le serveur transmet l'ID recherche les données d'état correspondant à l'utilisateur.

Mon approche ici consiste à définir un identifiant de session dans le cookie Lorsque le programme a besoin d'obtenir le statut d'utilisateur, l'identifiant de session sera utilisé comme clé de recherche dans Redis.

2. En même temps, la session aide les utilisateurs à recycler la session s'ils n'y accèdent pas pendant un certain temps.

Emprunter la fonctionnalité de Keys in Redis qui prend en charge le délai d'expiration pour prendre en charge cette fonction, mais en termes de renouvellement, le programme doit intercepter la demande et appeler cette méthode par lui-même (la démo a des exemples)

Démarrez la description du code ci-dessous

3.Interface d'appel de Redis

Référencez d'abord la DLL associée à ServiceStack.

Ajouter une configuration dans web.config Cette configuration est utilisée pour définir l'adresse d'appel Redis pour chaque service séparée par [,]. L'hôte est écrit en premier

<appSettings>

    <!--每台Redis之间用,分割.第一个必须为主机-->
    <add key="SessionRedis" value="127.0.0.1:6384,127.0.0.1:6384"/>

</appSettings>
Copier après la connexion

Configuration initiale

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
            });
        }
Copier après la connexion

Un délégué est écrit à des fins de contrôle

/// <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();
                }
            }
        }
Copier après la connexion

Pour un exemple d'appel, veuillez consulter le code source de autres détails

/// <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);
        }
Copier après la connexion

4. Implémenter la session

Écrivez un identifiant de session dans le cookie comme mentionné ci-dessus

/// <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;
            }
        }

    }
Copier après la connexion

Comment accéder à l'utilisateur

/// <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));
        }
Copier après la connexion

6.

Par défaut, l'utilisateur est déconnecté après une absence de visite pendant plus de 30 minutes, donc à chaque visite de l'utilisateur, le temps de déconnexion de l'utilisateur doit être reporté de 30 minutes

Cela nécessite d'appeler le Méthode de renouvellement 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);
        }
Copier après la connexion

Après encapsulation

/// <summary>
/// 续期
/// </summary>
public void Postpone()
{
new RedisClient<object>().KSetEntryIn(SessionId, new TimeSpan(0, Managers.TimeOut, 0));
}
Copier après la connexion

Ici, j'ai utilisé l'ActionFilter dans MVC3 pour intercepter toutes les demandes des utilisateurs

namespace Test
{
    public class SessionFilterAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// 每次请求都续期
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            new Session(filterContext.HttpContext).Postpone();
        }
    }
}
Copier après la connexion

Enregistrez-le dans Global.asax

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new SessionFilterAttribute());
        }

        protected void Application_Start()
        {
            RegisterGlobalFilters(GlobalFilters.Filters);
        }
Copier après la connexion

5. Méthode d'appel

Afin de faciliter l'appel et l'emprunt des nouvelles fonctionnalités de la version 4.0, ajoutez un attribut étendu à la méthode d'appel du contrôleur

public static class ExtSessions
{public static Session SessionExt(this Controller controller)
    {
        return new Session(controller.HttpContext);
    }
}
Copier après la connexion

 :

public class HomeController : Controller
    {
        public ActionResult Index()
        {
            this.SessionExt().IsLogin();
            return View();
        }
    }
Copier après la connexion

6. Téléchargement du code

Cliquez pour télécharger

7. Suivi

SessionManager comprend l'obtention du nombre de listes d'utilisateurs, se déconnecter d'un utilisateur et obtenir des informations utilisateur basées sur l'ID utilisateur, la liste d'objets utilisateur en ligne, la liste SessionId de l'utilisateur en ligne et d'autres méthodes

La fonction de connexion utilisateur sera implémentée en un seul endroit à l'avenir

Recommandations associées : Tutoriel sur la base de données Redis

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:cnblogs.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!