幽灵谷

追求永无止境......
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

ASP.NET解决单用户登录问题

Posted on 2010-04-08 15:34  zhb6022  阅读(1472)  评论(0编辑  收藏  举报

所谓单用户登陆的意思是不允许相同的帐号同时登陆系统,唯一帐号与系统操作同步。(本人理解范围,有不准确的请指正!)

这里主要是解决WEB系统的单用户登陆问题:

1.与WEB服务器对话我们采取SESSION对象,模式为进程。因为只有使用 Session的进程模式,Session过有效期时才能触发Session_End事件。

2.使用application对象来做服务器端标识。

3.使用Session 对象,当它到期时触发Session_End事件,利用这个机制来改变application中的值。

下面为解决的具体代码和实施步骤:

1.在VS2005中创建一个SingleLogin.cs类文件,类名定义为SingleLogin

创建两个方法void UserLogin(object id),bool IsLogin(object id)

具体代码:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

/// <summary>
/// SingleLogin 的摘要说明
/// </summary>
public class SingleLogin
{
    private readonly string appKey = "online";
    private readonly string logout = "{$}";

 public SingleLogin(){}

    /// <summary>
    /// 用户登陆操作
    /// </summary>
    /// <param name="id">为用户ID或用户名这个必须是用户的唯一标识</param>
    public void UserLogin(object id)
    {
        System.Collections.Hashtable ht = (System.Collections.Hashtable)HttpContext.Current.Application[appKey];
        if(ht==null)ht = new System.Collections.Hashtable();     

        System.Collections.IDictionaryEnumerator IDE = ht.GetEnumerator();

        while (IDE.MoveNext())
        {
            if (IDE.Value.ToString().Equals(id.ToString()))
            {
                ht[IDE.Key.ToString()] = logout;
                break;
            }
        }

        ht[HttpContext.Current.Session.SessionID] = id.ToString();
        HttpContext.Current.Application.Lock();
        HttpContext.Current.Application[appKey] = ht;
        HttpContext.Current.Application.UnLock(); 
    }

    /// <summary>
    /// 判断某用户是否已经登陆
    /// </summary>
    /// <param name="id">为用户ID或用户名这个必须是用户的唯一标识</param>
    /// <returns>true为没有登陆 flase为被迫下线</returns>
    public bool IsLogin(object id)
    {
        bool flag = true;
        string uid = id.ToString();
        System.Collections.Hashtable ht = (System.Collections.Hashtable)HttpContext.Current.Application[appKey];
        if (ht != null)
        {
            System.Collections.IDictionaryEnumerator IDE = ht.GetEnumerator();
            while (IDE.MoveNext())
            {
                //找到自己的登陆ID
                if (IDE.Key.ToString().Equals(HttpContext.Current.Session.SessionID))
                {
                    //判断用户是否被注销
                    if (IDE.Value.ToString().Equals(logout))
                    {
                        ht.Remove(HttpContext.Current.Session.SessionID);
                        HttpContext.Current.Application.Lock();
                        HttpContext.Current.Application[appKey] = ht;
                        HttpContext.Current.Application.UnLock();             
                        HttpContext.Current.Session.RemoveAll();
                        HttpContext.Current.Response.Write("<script type='text/javascript'>alert('你的帐号已在别处登陆,你被强迫下线!')</script>");
                        flag = false;
                    }
                    break;
                }
            }
        }
        return flag;
    }
}

void UserLogin(object id)方法主要是执行用户登陆时候的操作。

它的实现的功能是:当有相同帐号的时候,对有相同帐号的用户改变一个系统固定的值,以标识被改变的值的用户将被迫下线。

bool IsLogin(object id)用来判断用户的登录情况,如果有同一帐号登录那么后登录的用户将被迫下线,这是为了解决,如果用户非法退出,Session采取进程模式必须要达到系统默认或设置的期限内才能触发Session_End事件来对applicatiion共享数据进行清除,否则这一帐户必须到达有效期后才能登录。

2.在项目中添加Global.asax全局文件主要是编写Session_End

代码:

Hashtable ht = (Hashtable)Application["online"];
        if (ht[Session.SessionID] != null)
        {
            ht.Remove(Session.SessionID);
            Application.Lock();
            Application["Online"] = ht;
            Application.UnLock();
        }