这两天项目中需要实现一个用户这边登录了,就把已经登录的人,强制下线!

 刚开始想的是清空SESSION里面值,但是SESSION是在Request的时候才有的,Request的时候会有一个SessionID值传过来,来区分Session的唯一性!每个客户端对应一个Session,这样我就无法在这个客户端,去清空别个客户端的Session值,所以这个不能用(cookie同理)!

    然后想到了Application,把所有登录过的用户保存到一个Hashtable里面 键用 SessionID + User.LoginName,因为存在一个客户端登录多个用户,这样才能让Key唯一化!值就保存当前 用户的实例!当另外一个客户端用户登录的时候会就去查询这个用户是否在Hastable中存在,当用户存在的时候就移除已经登录的那个,重新添加当前的SessionID进去(其实就是替换key)!然后再将Hashtable保存到Application中去!

    对了,每次去取用户的时候先去 根据当前SessionID+User.LoginName  这个key  去查询 它在不在Hashtable 并且 Session["user"] 不为NULL的话,就说明别人在别出登录了!这下就返回NULLUser,并把Session["user"]注销掉! 当登录用户取不到的时候,我们就把页面转到登录页面去!并提示用户已经在别处登录,您被强制下线!

   当然还有一个问题就是保存在Application中的值,只要重启服务器,它才会消失!所以我们需要定时清理Hashtable中的值,当然最好的办法就是让它和Session一起过期!Session有一个过期事件,可以在那里把Hashtable中的键值移除掉,当然只是移除当前的键值,而不是所有的!

  下面贴出Demo代码!小弟第一次写blog,还请多多谅解!小弟拙见,请大神指点!

 

 

 


登录页面 登录的方法里面

 

 

--


 string name = this.tb_name.Text;
            Hashtable ht = (Hashtable)Application["online"];//获取当前用户列表
            Session["name"] = name;
            if (ht == null)//用户列表如果为NULL
            {
                ht = new Hashtable();
                ht.Add(Session.SessionID, name);//将当前用户添加
                Application["online"]=ht;
                Response.Redirect("/Control.aspx");
            }
            else//不为NULL,查询用户是否在其中
            {
                string key;
                DictionaryEntry de = new DictionaryEntry();//保存的键值
                foreach (DictionaryEntry item in ht)
                {
                        if (item.Key.ToString() != Session.SessionID && item.Value.ToString() == name)//有人登录了
                        {
                            //移除 DictionaryEntry
                            ht.Remove(item.Key);
                            //重新添加 DictionaryEntry
                            ht.Add(Session.SessionID, name);
                        }
                        de = item;
                        break;
                }
                Application["online"] = ht;
                Response.Redirect("/Control.aspx");
            }

 

 

登录成功的页面

 

 

 

--


protected void Page_Load(object sender, EventArgs e)
        {
            Hashtable ht = (Hashtable)Application["online"];
            if (ht ==null)
            {
                this.lbl_loginState.Text = "您未登录!";
            }
            else
            {
                bool isExists = false;
                foreach (DictionaryEntry item in ht)
                {
                    if (item.Key.ToString() == Session.SessionID)
                    {
                        isExists = true;
                        break;
                    }
                }

                foreach (DictionaryEntry item in ht)
                {
                    Response.Write("key:" + item.Key.ToString() + "<br/>" + item.Value.ToString() + "<br/><br/><br/><br/>");
                }

                if (!isExists)
                {
                    this.lbl_loginState.Text = "对不起,此号在别处登录,您被强制下线!"+Session.SessionID;
                }
                else
                {
                    this.lbl_loginState.Text = "登录成功!"+Session.SessionID;
                }
            }
        }

 

 

Session过期的时候

 

 

 

--


 

 void Session_End(object sender, EventArgs e)
        {
            //当Session过期的时候也把HashTable中用户移除
            Hashtable ht = (Hashtable)Application["online"];
            if (ht != null && ht.Count > 0)
            {
                foreach (DictionaryEntry item in ht)
                {
                    if (item.Key.ToString().IndexOf(Session.SessionID)!=-1)
                    {
                        ht.Remove(item.Key);
                    }
                }
            }

            Response.Redirect("/Account/Login");

            // 在会话结束时运行的代码。
            // 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
            // InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer
            // 或 SQLServer,则不会引发该事件。

        }

 

。。。。。这个编辑器第一次用,排版很乱,sorry!!!

posted on 2012-09-20 12:13  Jun.C  阅读(259)  评论(0)    收藏  举报