这两天项目中需要实现一个用户这边登录了,就把已经登录的人,强制下线!
刚开始想的是清空SESSION里面值,但是SESSION是在Request的时候才有的,Request的时候会有一个SessionID值传过来,来区分Session的唯一性!每个客户端对应一个Session,这样我就无法在这个客户端,去清空别个客户端的Session值,所以这个不能用(cookie同理)!
然后想到了Application,把所有登录过的用户保存到一个Hashtable里面 键用 SessionID + User.LoginName,因为存在一个客户端登录多个用户,这样才能让Key唯一化!值就保存当前 用户的实例!当另外一个客户端用户登录的时候会就去查询这个用户是否在Hastable中存在,当用户存在的时候就移除已经登录的那个,重新添加当前的SessionID进去(其实就是替换key)!然后再将Hashtable保存到Application中去!
对了,每次去取用户的时候先去 根据当前SessionID+User.LoginName 这个key 去查询 它在不在Hashtable 并且 Session["user"] 不为NULL的话,就说明别人在别出登录了!这下就返回NULLUser,并把Session["user"]注销掉! 当登录用户取不到的时候,我们就把页面转到登录页面去!并提示用户已经在别处登录,您被强制下线!
当然还有一个问题就是保存在Application中的值,只要重启服务器,它才会消失!所以我们需要定时清理Hashtable中的值,当然最好的办法就是让它和Session一起过期!Session有一个过期事件,可以在那里把Hashtable中的键值移除掉,当然只是移除当前的键值,而不是所有的!
下面贴出Demo代码!小弟第一次写blog,还请多多谅解!小弟拙见,请大神指点!
登录页面 登录的方法里面
--
string name = this.tb_name.Text;
Hashtable ht = (Hashtable)Application["online"];//获取当前用户列表
Session["name"] = name;
if (ht == null)//用户列表如果为NULL
{
ht = new Hashtable();
ht.Add(Session.SessionID, name);//将当前用户添加
Application["online"]=ht;
Response.Redirect("/Control.aspx");
}
else//不为NULL,查询用户是否在其中
{
string key;
DictionaryEntry de = new DictionaryEntry();//保存的键值
foreach (DictionaryEntry item in ht)
{
if (item.Key.ToString() != Session.SessionID && item.Value.ToString() == name)//有人登录了
{
//移除 DictionaryEntry
ht.Remove(item.Key);
//重新添加 DictionaryEntry
ht.Add(Session.SessionID, name);
}
de = item;
break;
}
Application["online"] = ht;
Response.Redirect("/Control.aspx");
}
登录成功的页面
--
protected void Page_Load(object sender, EventArgs e)
{
Hashtable ht = (Hashtable)Application["online"];
if (ht ==null)
{
this.lbl_loginState.Text = "您未登录!";
}
else
{
bool isExists = false;
foreach (DictionaryEntry item in ht)
{
if (item.Key.ToString() == Session.SessionID)
{
isExists = true;
break;
}
}
foreach (DictionaryEntry item in ht)
{
Response.Write("key:" + item.Key.ToString() + "<br/>" + item.Value.ToString() + "<br/><br/><br/><br/>");
}
if (!isExists)
{
this.lbl_loginState.Text = "对不起,此号在别处登录,您被强制下线!"+Session.SessionID;
}
else
{
this.lbl_loginState.Text = "登录成功!"+Session.SessionID;
}
}
}
Session过期的时候
--
void Session_End(object sender, EventArgs e)
{
//当Session过期的时候也把HashTable中用户移除
Hashtable ht = (Hashtable)Application["online"];
if (ht != null && ht.Count > 0)
{
foreach (DictionaryEntry item in ht)
{
if (item.Key.ToString().IndexOf(Session.SessionID)!=-1)
{
ht.Remove(item.Key);
}
}
}
Response.Redirect("/Account/Login");
// 在会话结束时运行的代码。
// 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
// InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer
// 或 SQLServer,则不会引发该事件。
}
。。。。。这个编辑器第一次用,排版很乱,sorry!!!
浙公网安备 33010602011771号