Web 项目中经常遇到的问题就是同一用户名多次登陆的问题,相应的解决办法也很多,总结起来不外乎这几种解决办法:将登陆后的用户名放到数据库表中; 登陆后的用户名放到Session中;登陆后的用户名放到Application中;登陆后的用户名放到Cache中。一般的这几种方法都是登陆了之后,如果没有正常退出, 第二次登陆将不被允许。这样一般都会存在一个问题:如果用户没有正常退出系统,那么他接下来继续登陆的时候,因为Session没有过期等问题,会被拒绝 继续登陆系统,只能等待Session过期后才能登陆。本文介绍的方法是第二次登陆时会把第一次的登陆注销掉,第一次登陆将会提示信息:您的帐号已另一地 点登录,您被强迫下线的提示信息。
功能实现代码:
1.登录之后调用下面代码
//获取当前项目存储的登录用户sessionid与用户id
Hashtable hOnline = (Hashtable)Application["Online"];
if (hOnline != null && hOnline.Count > 0)
{ IDictionaryEnumerator idE = hOnline.GetEnumerator();
string strKey = "";
while (idE.MoveNext())
{
//判断当前用户是否已经登录,如果已经登录,上次登录用户的用户id置为特殊内容,便于后面判断是否已经登录过,本项目中使用 了“XXXXXX”
if (idE.Value != null && idE.Value.ToString().Equals(model.usrid.ToString()))
{
strKey = idE.Key.ToString();
hOnline[strKey] = "XXXXXX";
break;
}
}
}
else
{ hOnline = new Hashtable();
}
//记录当前登录用户的sessionid以及value值
hOnline[Session.SessionID] = model.usrid.ToString();
//修改Application
Application.Lock();
Application["Online"] = hOnline;
Application.UnLock();
2.每一个页面重写或者OnInit方法,本项目中是写在了基类中,每一个页面继承了基类:
protected override void OnInit(EventArgs e){
Hashtable hOnline = (Hashtable)Application["Online"];
if (hOnline != null && hOnline.Count > 0)
{
IDictionaryEnumerator idE = hOnline.GetEnumerator();
while (idE.MoveNext())
{
if (idE.Key != null && idE.Key.ToString().Equals(Session.SessionID))
{
//already login
if (idE.Value != null && "XXXXXX".Equals(idE.Value.ToString()))
{
hOnline.Remove(Session.SessionID);
Application.Lock();
Application["Online"] = hOnline;
Application.UnLock();
Response.Write("<Script Language=Javascript>alert('您的帐号已在另一地点登录,您被迫下线!');</Script>");
//url为需要调整的页面
Response.Write("<Script Language=Javascript>window.top.location.href='" + url + "';</Script>");
Response.End();
return;
}
}
}
}
}
3.当前用户session超时,需要清除当前用户的信息(本项目中是将方法提取出来,再global文件中调用):
/// <summary>
/// Global文件的SessionEnd事件中增加此代码
/// </summary>
public static void GlobalSessionEnd()
{
Hashtable hOnline = (Hashtable)System.Web.HttpContext.Current.Application["Online"];
if (hOnline[System.Web.HttpContext.Current.Session.SessionID] != null)
{
hOnline.Remove(System.Web.HttpContext.Current.Session.SessionID);
System.Web.HttpContext.Current.Application.Lock();
System.Web.HttpContext.Current.Application["Online"] = hOnline;
System.Web.HttpContext.Current.Application.UnLock();
}
}
4.global文件中调用上面的方法:
protected void Session_End(Object sender, EventArgs e)
{
GlobalSessionEnd();
}
5.当用户正常退出时,在退出对应的事件中调用上面的方法;
GlobalSessionEnd();