前几天在博客园看到一个帖子,讨论两个整数集合比较的算法问题。呵呵,其实任何整数集合的问题都是可以通过位图算法解决。简单地说,就是把值转化为数组下标,将O(n)复杂度降低到O(1)复杂度来获得最高效率。当然,会牺牲一点点空间。
解决单纯的整数集合比较问题,只是纯理论的。实际上,位图算法可以应用在用户登录之后的接口验证上。服务端的设计其实也没什么复杂的地方,就是维护一个数组罢了。只不过这个数组并非是简单的整数集合,而是一个对象List。这个设计的最大优点是在验证方法中,不是通过find方法而是直接访问下标获得对象,更无需查询数据库,可谓是将时间消耗降低到了极致。
好吧,下面看代码,首先是Session类,该类承载了一些必要的用户信息。其中最关键的属性是ID,这个ID的值就是该对象在List
public class Session
{
///
/// 自增ID
///
public int ID { get; set; }
///
/// 会话ID
///
public Guid SessionId { get; set; }
///
/// 登录用户ID
///
public Guid UserId { get; set; }
///
/// 登录部门ID
///
public Guid? DeptId { get; set; }
///
/// 用户账号
///
public string LoginName { get; set; }
///
/// 登录用户名
///
public string UserName { get; set; }
///
/// 登录部门全称
///
public string DeptName { get; set; }
///
/// WCF服务基地址
///
public string BaseAddress { get; set; }
///
/// 用户签名
///
public string Signature { get; set; }
///
/// 用户状态
///
public bool Validity { get; set; }
///
/// 用户机器码
///
public string MachineId { get; set; }
///
/// 上次连接时间
///
public DateTime LastConnect { get; set; }
///
/// 用户登录状态
///
public LoginResult LoginStatus { get; set; }
}
public class OnlineManage
{
///
/// 用户会话列表
///
public static List Sessions { get; set; }
///
/// 最大在线用户数
///
public static int MaxAuthorized { get; set; }
///
/// 构造方法
///
public OnlineManage()
{
Sessions = new List();
MaxAuthorized = Convert.ToInt32(ConfigurationManager.AppSettings["MaxAuthorized"]);
}
///
/// 会话合法性验证
///
///
///
public static bool Verification(Session obj)
{
if (obj == null || obj.ID >= Sessions.Count) return false;
var us = Sessions[obj.ID];
if (us.SessionId != obj.SessionId || us.Signature != obj.Signature || !us.Validity) return false;
us.LastConnect = DateTime.Now;
return true;
}
}
///
/// 获取用户登录结果
///
/// Session对象实体
/// Session对象实体
public Session UserLogin(Session obj)
{
if (obj == null) return null;
if (OnlineManage.Sessions.Count >= OnlineManage.MaxAuthorized)
{
obj.LoginStatus = LoginResult.Unauthorized;
return obj;
}
var pw = obj.Signature;
var us = OnlineManage.Sessions.Find(s => s.LoginName == obj.LoginName);
if (us == null)
{
var user = CommonDAL.GetUser(obj.LoginName);
if (user == null)
{
obj.LoginStatus = LoginResult.NotExist;
return obj;
}
obj.ID = OnlineManage.Sessions.Count;
obj.UserId = user.ID;
obj.UserName = user.Name;
obj.Signature = user.Password;
obj.Validity = user.Validity;
OnlineManage.Sessions.Add(obj);
us = OnlineManage.Sessions[obj.ID];
}
else if (us.SessionId != Guid.Empty)
{
us.LoginStatus = us.MachineId != obj.MachineId ? LoginResult.Online : LoginResult.Multiple;
}
else
{
us.SessionId = obj.SessionId;
us.LoginStatus = LoginResult.Success;
}
// 用户被封禁
if (!us.Validity) us.LoginStatus = LoginResult.Banned;
// 密码不正确
if (us.Signature != pw) us.LoginStatus = LoginResult.Failure;
us.LastConnect = DateTime.Now;
return us;
}
///
/// 删除在线用户会话
///
/// Session对象实体
/// 要删除Session的ID
/// bool 是否删除成功
public bool DelOnlineUser(Session us, int? sid)
{
if (us == null) return false;
if (!OnlineManage.Verification(us)) return false;
OnlineManage.Sessions[sid ?? us.ID].SessionId = Guid.Empty;
return true;
}
///
/// 根据ID封禁/解封用户
///
/// 用户会话
/// 用户ID
/// true:解封;false:封禁
/// bool 是否更新成功
public bool UpdateUserStatus(Session us, Guid id, bool validity)
{
if (!OnlineManage.Verification(us)) return false;
var sql = string.Format("update SYS_User set Validity = '{0}' where ID = '{1}'", validity, id);
if (SqlHelper.SqlNonQuery(sql) > 0)
{
OnlineManage.Sessions.Find(s => s.UserId == id).Validity = validity;
return true;
}
return false;
}