所谓单用户登陆的意思是不允许相同的帐号同时登陆系统,唯一帐号与系统操作同步。(本人理解范围,有不准确的请指正!)
这里主要是解决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();
}