急了,寻切实可行的防重复登录的解决方案。

cyhcyhhychyc 2010-10-22 09:42:29
要求:同一账号,某人先登录后,第二个人再登录,拒绝登录;第一个人下线后,第二个人方可登录。第一个人下线后,系统要及时知道,不能让第二个人一直无法登录。
BS结构。
大家谁有切实做过的,放代码或者说要点都行。可行的分数全给。
本人现在是用cache来做,但是理论上可行的流程,执行起来就是不行。比如设置一个绝对过期时间,到期了这个cache就是不过期
请不要在网上搜索一些结果来贴,你能搜索到的我已经搜索到。有些不合适,有些根本不行。
...全文
609 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
kkbac 2010-10-23
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 jianzhang5555 的回复:]

我觉得放在数据库中是不可行的,加入你登陆了,然 后断电了,
这样就不行了。
[/Quote]

服务器断电的因素都需要考虑吗?
Bodil 2010-10-23
  • 打赏
  • 举报
回复
登录状态记录在数据库中
不管断电还是什么的都可以避免

在session_end中情调登录状态,如果遇到非正常关闭

就在数据库中记录一个 “登录后最后一次活动时间”,当下一个登录者登录时,如果超过这个“最后一次活动时间”多长时间就可以强制登录上去,你可以限定这个间隔时间是多长。。。。。

我觉得这样能实现你的要求了吧
yaazz 2010-10-23
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 jianzhang5555 的回复:]
我觉得放在数据库中是不可行的,加入你登陆了,然 后断电了,
这样就不行了。
[/Quote]
可以加超时的

不过还是踢掉上一个比较合理
gahyyai 2010-10-23
  • 打赏
  • 举报
回复
mark....

骑猪看海 2010-10-23
  • 打赏
  • 举报
回复
LZ这设计不好吧,我要是盗了你的号一直不下线,那你不是就上不去了。应该说是后一个人登陆,前一个人就挤下线合理些。这样的话也好做多了
cyhcyhhychyc 2010-10-23
  • 打赏
  • 举报
回复
现在 的问题是:下面的session_end,调试时发现新打开页面也会调用。比如同一账号用ie登陆了;把url复制到另一个非ie浏览器,会发现session_end也调用了。结果使得整个方案失败。没有明白,为什么新开页面也会和调用session_end

void Session_End(object sender, EventArgs e)
{

HttpRuntime.Cache.Remove(this.Session.SessionID);
}
danjiewu 2010-10-23
  • 打赏
  • 举报
回复

public void JustReadIt()
{

if (Cache[Lab.MY("Name").ToString()] == null)
{
}
}

你确定这个6秒之内至少被调用一次吗?调试下看看
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 net_lover 的回复:]
你不能设置 Cache的过期时间啊,你需要设置 Session的过期。在Session的End里删除 Cache里面的登录记录。这样就能在异常关闭时自动在 Session失效时删除登录记录
[/Quote]
但是Session在注销什么的不好控制。还有就是浏览器不同,这个也不好用
觉得还是需要数据库的
wuyq11 2010-10-22
  • 打赏
  • 举报
回复
SessionID,用户账号,最后访问时间
判断离线以超时为主要依据.判断以10~60秒钟为好
孟子E章 2010-10-22
  • 打赏
  • 举报
回复
这个需求没有十全十美的方案:
采用ajax 定时器,是最准确的,但如果页面很多,采用这种方法是稍显麻烦,但是,如果每个页面包含一个js文件,则也是可以解决的。这种方法对服务器要求高,最好单独设置一台服务器只做这项功能。
anliuty 2010-10-22
  • 打赏
  • 举报
回复
基本不用HttpContext.Current.Cache这个东西,做缓存我都是放到静态类中去维护,主要是看它既然是在HttpContext.Current下,以为是当前会话私有的东西,呵呵,没有测试没有发言权,lz请当没看到
jiao3630 2010-10-22
  • 打赏
  • 举报
回复
直接在数据库用户表里加一列表示用户状态 登录注销时判断
孟子E章 2010-10-22
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 anliuty 的回复:]
我觉得你使用HttpContext.Current.Cache这个Cache,它是将数据存储在当前登录用户的会话中的,当另一个人用这个账号登录的时候,虽然账号相同,但是会话是不同的,第二个人登录时取不到第一个人的缓存信息,当然无从判断是否过期,

你应该把账号登录的标志放到一个公用的缓存当中,比如一个静态类当中,这样才可以共用缓存数据
[/Quote]

Cache是每个人都能访问的,Cache里面的key就是用户名,当然这个Cache["key"]存在说明该账户已经登录了,任何一个人都能读到
int64 2010-10-22
  • 打赏
  • 举报
回复
已经是多年的问题了
anliuty 2010-10-22
  • 打赏
  • 举报
回复
我觉得你使用HttpContext.Current.Cache这个Cache,它是将数据存储在当前登录用户的会话中的,当另一个人用这个账号登录的时候,虽然账号相同,但是会话是不同的,第二个人登录时取不到第一个人的缓存信息,当然无从判断是否过期,

你应该把账号登录的标志放到一个公用的缓存当中,比如一个静态类当中,这样才可以共用缓存数据
zsc970 2010-10-22
  • 打赏
  • 举报
回复
这问题一定要在服务器端完成吧,客户端的东西肯定不成的,那就只有用application了,但它必须要客户按规定退出才好清除,否则就长期有效,第二个客户就登录不了,现在的问题是如何定时清除下线了的application.这样成不成:application中记录用户名外,同时保存它的访问ID,当第二个人登录时,先检查它的ID是否是原来的ID,如果否,用原来的ID去查看第一个用户下线没有,就能解决你的问题.
ruolins 2010-10-22
  • 打赏
  • 举报
回复
我觉得放在数据库中是不可行的,加入你登陆了,然 后断电了,
这样就不行了。
孟子E章 2010-10-22
  • 打赏
  • 举报
回复
使用服务器变量有一个缺点,就是多个工作进程的情况下,是无法使用的,采用数据库记录是最可靠的
孟子E章 2010-10-22
  • 打赏
  • 举报
回复
下面是一个完整的例子。你可以拷贝测试下
<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

protected void Login_Click(object sender, EventArgs e)
{
// 作为唯一标识的Key,应该是唯一的,这可根据需要自己设定规则。
// 做为测试,这里用用户名和密码的组合来做标识;也不进行其它的错误检查。

//判断用户名和密码,省略
// 生成Key
string sKey = UserName.Text;
// 得到Cache中的给定Key的值
string sUser = Convert.ToString(Cache[sKey]);
// 检查是否存在
if (sUser == null || sUser == String.Empty)
{
// Cache中没有该Key的项目,表名用户没有登录,或者已经登录超时
// 注意下面使用的TimeSpan构造函数重载版本的方法,是进行是否登录判断的关键。
TimeSpan SessionTimeOut = new TimeSpan(0, 0, System.Web.HttpContext.Current.Session.Timeout, 0, 0);
HttpContext.Current.Cache.Insert(sKey, sKey, null, DateTime.MaxValue, SessionTimeOut,
System.Web.Caching.CacheItemPriority.NotRemovable, null);
Session["User"] = sKey;
// 首次登录,您可以做您想做的工作了。
Msg.Text = "<h4 style='color:red'>嗨!欢迎您访问<a href='http://dotnet.aspx.cc/'>【孟宪会之精彩世界】";
Msg.Text += "</a>,祝您浏览愉快!:)</h4>";
}
else
{
// 在 Cache 中发现该用户的记录,表名已经登录过,禁止再次登录
Msg.Text = "<h4 style='color:red'>抱歉,您好像已经登录了呀:-(</h4>";
return;
}
}

protected void Page_Load(object sender, EventArgs e)
{
Time.Text = "自动失效时间(分钟):" + System.Web.HttpContext.Current.Session.Timeout.ToString();
}

protected void Button1_Click(object sender, EventArgs e)
{
if (Session["User"]!=null)
HttpContext.Current.Cache.Remove(Session["User"].ToString());
}
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div align="center">
<h3>单点登录测试</h3>
<p>用户名称:<asp:TextBox ID="UserName" runat="server"></asp:TextBox></p>
<p>用户密码:<asp:TextBox ID="PassWord" runat="server" TextMode="Password"></asp:TextBox></p>
<p>
<asp:Button ID="Login" runat="server" Text=" 登 录 " OnClick="Login_Click"></asp:Button>
<asp:Button ID="Button1" runat="server" Text="撤销登录" onclick="Button1_Click" />
</p>
<p>
<asp:Label ID="Msg" runat="server"></asp:Label></p>
</div>
<asp:Literal ID="Time" runat="server"></asp:Literal>
</form>
</body>
</html>
wuyq11 2010-10-22
  • 打赏
  • 举报
回复
单点登录。记录用户登录状态和日志
登出后修改状态,关闭IE等Session的End无法执行
timer定时查询用户操作的时间差是否符合范围,修改状态
加载更多回复(5)

62,272

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧