zoukankan      html  css  js  c++  java
  • [转]利用HttpModuler实现WEB程序同一时间只让一个用户实例登陆

    我在们使用ASP.Net开发WEB网站时,有的时候是不让同一个用户名在同一时间进行多次登陆的。
    为了不影响原来的整个网站,我选择使用了HttpModuler来实现。
    先让所有的Page从自己的Page类:BasePage类继承,并实现 ISigleLogin接口。相关代码如下:

         public interface ISingleLogin
        {
            string SigleUserLoginId { get; }
    
            void SigleUserLogout();
    
        }
    BasePage类:
    public class BasePage : System.Web.UI.Page , BNet.Web.Modulers.ISingleLogin
    {
        public BasePage()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }
    
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (Session["UserId"] == null)
            {
                Response.Write("你还没有登陆");
                Response.Redirect("login.aspx");
            }
        }
    
        #region ISingleLogin 成员
    
        public string SigleUserLoginId
        {
            get 
            {
                if (Session["UserId"] != null)
                {
                    return Session["UserId"].ToString();
                }
                else
                    return "";
            }
        }
    
        public void SigleUserLogout()
        {
            Session.Abandon();
            Response.Write("你在别处已经登陆,强制退出本次登陆!");
        }
    
        #endregion
    }

    然后在Web.config中加入HttpModuler:

    <system.web>
     <httpModules>
     <add name="SingleLogin" type="BNet.Web.Modulers.SingleLoginModuler"/>
     </httpModules>
    </system.web>

    相关的SigleLoginModuler代码如下:

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.UI;
    
    namespace BNet.Web.Modulers
    {
        //// <summary>
        /// SingleLoginModuler 的摘要说明
        /// </summary>
        public class SingleLoginModuler : System.Web.IHttpModule
        {
            const string sigle_login_userid = "evlon_siglelogin_userid";
            const string sigle_pre_logout_sessionid = "evlon_sigle_pre_logout_sessionid";
    
            public static StringLifeValueDictionary UsableGetter(ref StringLifeValueDictionary dic)
            {
                if (dic == null)
                {
                    dic = new StringLifeValueDictionary();
                }
                else
                {
                    List<string> listRemove = new List<string>();
                    StringLifeValueDictionary.Enumerator iter = dic.GetEnumerator();
                    while (iter.MoveNext())
                    {
                        if (iter.Current.Value.life < DateTime.Now)
                        {
                            listRemove.Add(iter.Current.Key);
                        }
                    }
    
                    foreach (string key in listRemove)
                    {
                        dic.Remove(key);
                    }
                }
    
                return dic;
            }
    
            static StringLifeValueDictionary loginedUserIdDictionary = null;
            static StringLifeValueDictionary LoginedUserIdDictionary
            {
                get
                {
                    return UsableGetter(ref loginedUserIdDictionary);
                }
            }
    
            static StringLifeValueDictionary preLogoutSessionIdDictionary = null;
            static StringLifeValueDictionary PreLogoutSessionIdDictionary
            {
                get
                {
                    return UsableGetter(ref preLogoutSessionIdDictionary);
                }
            }
    
            public SingleLoginModuler()
            {
                //
                // TODO: 在此处添加构造函数逻辑
                //
            }
    
            #region IHttpModule 成员
    
            public void Dispose()
            {
            }
    
            public void Init(HttpApplication context)
            {
                context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
                context.PostRequestHandlerExecute += new EventHandler(context_PostRequestHandlerExecute);
    
            }
    
    
    
            void context_PreRequestHandlerExecute(object sender, EventArgs e)
            {
                HttpApplication context = sender as HttpApplication;
                IHttpHandler httpHandler = context.Context.CurrentHandler;
                ISingleLogin sl = httpHandler as ISingleLogin;
                if (sl != null)
                {
                    string suid = sl.SigleUserLoginId;
                    if (suid != string.Empty)
                    {
                        if (PreLogoutSessionIdDictionary.ContainsKey(context.Session.SessionID))
                        {
                            //这个用户应该强制登出
                            PreLogoutSessionIdDictionary.Remove(context.Session.SessionID);
    
                            Page page = (Page)httpHandler;
                            page.PreInit += new EventHandler(page_PreInit);
    
                        }
                        else if (!LoginedUserIdDictionary.ContainsKey(suid))
                        {
                            LoginedUserIdDictionary.Add(suid, new LifeValue(context.Session.SessionID));
                        }
                    }
                }
    
            }
    
            void page_PreInit(object sender, EventArgs e)
            {
                Page page = sender as Page;
                ISingleLogin sl = page as ISingleLogin;
                if (sl != null)
                {
                    sl.SigleUserLogout();
                    page.Response.End();
                }
            }
    
            void context_PostRequestHandlerExecute(object sender, EventArgs e)
            {
                //从LogineduserId 里找到和当前用户一样的用户ID的SessionId
                HttpApplication context = sender as HttpApplication;
                IHttpHandler httpHandler = context.Context.CurrentHandler;
                ISingleLogin sl = httpHandler as ISingleLogin;
                if (sl != null)
                {
                    string suid = sl.SigleUserLoginId;
                    if (suid != string.Empty)
                    {
                        if (LoginedUserIdDictionary.ContainsKey(suid))
                        {
                            string sessionId = LoginedUserIdDictionary[suid].value;
                            if (sessionId != context.Session.SessionID)
                            {
                                if (!PreLogoutSessionIdDictionary.ContainsKey(sessionId))
                                {
                                    PreLogoutSessionIdDictionary.Add(sessionId, new LifeValue(suid));
                                }
    
                                LoginedUserIdDictionary.Remove(suid);
                            }
                        }
                        else
                        {
                            LoginedUserIdDictionary.Add(sl.SigleUserLoginId, new LifeValue(context.Session.SessionID));
                        }
    
                    }
                }
            }
    
            #endregion
        }
    
        public class LifeValue
        {
            public string value;
            public DateTime life;
    
            public LifeValue(string value)
            {
                this.value = value;
                this.life = DateTime.Now.AddMinutes(HttpContext.Current.Session.Timeout + 5);
            }
        }
    
        public class StringLifeValueDictionary : Dictionary<string, LifeValue>
        {
    
        }
    
    
        public interface ISingleLogin
        {
            string SigleUserLoginId { get; }
    
            void SigleUserLogout();
    
        }
    }

    如此,只在在你自己的BasePage中改动相关的代码(只两三行)就可以实现功能了。

    文中代码完整下载地址

    原文地址:http://evlon.cnblogs.com QQ:evlion@qq.com

  • 相关阅读:
    METHODS OF AND APPARATUS FOR USING TEXTURES IN GRAPHICS PROCESSING SYSTEMS
    Display controller
    Graphics processing architecture employing a unified shader
    Graphics-Processing Architecture Based on Approximate Rendering
    Architectures for concurrent graphics processing operations
    Procedural graphics architectures and techniques
    DYNAMIC CONTEXT SWITCHING BETWEEN ARCHITECTURALLY DISTINCT GRAPHICS PROCESSORS
    Thermal zone monitoring in an electronic device
    System and method for dynamically adjusting to CPU performance changes
    Framework for Graphics Animation and Compositing Operations
  • 原文地址:https://www.cnblogs.com/dupeng0811/p/1493871.html
Copyright © 2011-2022 走看看