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();