zoukankan      html  css  js  c++  java
  • 权限管理——在线列表

    我们知道在后台管理系统中如何限制用户重复登陆是个讨论不觉的问题。一些人刚开始说在数据库里设置一个标志,当同样用户登录的时候就提示已经重复登陆,但是这里存在一个问题就是如果用户突然非法关机,那么其他的用户将永远无法登录。因此,这里要考虑两种情况,一个是用户已经登录的情况下,在有其他的用户用相同的帐号密码登录的时候可以让其他用户强制之前一个用户下线,这个很符合逻辑,既然都知道用户名和密码,那么系统就没办法判断到底哪个登录的是对的。因此,系统有权让知道密码的用户都可以登录系统。第二个还要防止用户非法关机之类的,一旦用户关机后,我们应该设置一个定时器,当然这个时间由我们自己来定义一个合理的时间,然后让服务器每到指定的时间就触发这个事件。不断的判断在线的用户列表中的用户是否已经达到指定的时间没有操作,如果是的话就把用户从在线列表中清除,让用户重新登陆。我觉得这样的设计比较合理,如果有更好的可以给我留言。 

        根据这样的需求,我们就定义个管理用户的系统类,它具有用户ID,用户名,开始时间,最后操作时间,最后操作网址,用户类型,在线时间,还有IP。定义完后,我们就需要定义一个来存储这些信息的集合。系统里是定义一个缓存辞典来存储这些信息。一共定义了2个辞典和一个双向链表。第一个是 Dictionary<string, LinkedListNode<TValue>> _MemberUserList;用来存储所有的会员信息。Dictionary<TKey, LinkedListNode<TValue>> _AllUserList;定义所有的信息,包括会员和游客。在定义一个 LinkedList<TValue> _TValueLink;双向链表进行排序。因为,我们要对链表进行增删改,来达到不断维护在线链表的功能,因此,必须定义一个锁,来限制同一个时间只能对在线列表进行读或者写操作,因此系统中定义了一个 protected ReaderWriterLock _CacheDataRwl = new ReaderWriterLock();锁。接下来就是要定义一个时间,前一篇我已经提到过的system.time.timer类来时间,让它根据指定的时间不断的触发事件。这里的事件就是不断的清除那些已经过期的用户。当然这个类的功能还不限于此,既然可以删除过期用户,当然要具有可以添加新的用户,和更新新的用户的功能。因此,这个类中重载了多种删除的方法。可以根据用户给定的键值也就是key来删除,也可以通过name属性来删除,因此这里要求,name和key一样都具有唯一性。不过在删除和增加的时候都要加锁。判断用户是否长时间都没有操作的方法很简单,只要把用户最后操作时间和当前时间进行判断,如果操作系统指定时间则说明超时,当然,这样也要求用户每访问一个页面的时候都要更新最后操作的时间。

         当然也可以把用户信息存在表中,其实方法大同小异,一个是放在内存中,一个放在数据库中,一个访问快点但是占用内存,另外一个速度慢点每次都要去连接数据库,但是可以存储大量的数据,因此可以满足有大量用户在线的需求。

     public class CacheOnline<TKey, TValue>
             where TKey : IComparable<TKey>
             where TValue : OnlineUser<TKey>, new()
    ...{...}
    跟想象中的类实在太不一样, 我也是才接触一天,有些错误也是难免的,
    CacheOnline<TKey, TValue>
    其中 TKey, TValue 就是泛型类型关键字,通常规定用大写字母T开头,包含在尖括号<>中,它实际上并不是一个类型,而更像是一个类型的蓝图。若要使用 GenericList<T>,客户端代码必须通过指定尖括号中的类型参数来声明和实例化构造类型。此特定类的类型参数可以是编译器识别的任何类型。(http://www.gzctu.com/blog/blogview.asp?id=250)

    再来看看
             where TKey : IComparable<TKey>
             where TValue : OnlineUser<TKey>, new()
    where关键字实现的是对类型参数的约束,(http://www.gzctu.com/blog/blogview.asp?id=251)这里则:TKey必须为IComparable接口,TValue必须为类OnlineUser(OnlineUser 类主要描述用户信息)而new()则 约束指定泛型类声明中的任何类型参数都必须有公共的无参数构造函数。当泛型类创建类型的新实例时,将此约束应用于类型参数.当与其他约束一起使用时,new() 约束必须最后指定:

    关于更多的就不再说了,实在说不清楚,也不是下子能明白的,多看看MSDN吧.
    泛型可用于变量的声明如
    Dictionary<string, LinkedListNode<TValue>> _MemberUserList;
    Dictionary 为泛型集合(http://www.gzctu.com/blog/blogview.asp?id=265)总之这里就是要把在线用户的信息方入这个集合里面去,
    然而,在声明变量地方看到三个关键字 LinkedListNode,LinkedList和ReaderWriterLock 其解释分别如下

    LinkedList<(Of <(T>)>) 为通用链表(http://msdn2.microsoft.com/zh-cn/library/he2s3bh7.aspx)

    LinkedList<(Of <(T>)>) 集合的每个元素都是 LinkedListNode<(Of <(T>)>)。LinkedListNode<(Of <(T>)>) 包含一个值、对其所属的 LinkedList<(Of <(T>)>) 的引用、对下一个节点的引用,以及对上一个节点的引用。(http://msdn2.microsoft.com/zh-cn/library/ahf4c754.aspx)

    ReaderWriterLock 用于同步对资源的访问。在任一特定时刻,它允许多个线程同时进行读访问,或者允许单个线程进行写访问。在资源不经常发生更改的情况下,ReaderWriterLock 所提供的吞吐量比简单的一次只允许一个线程的锁更高。

    在多数访问为读访问,而写访问频率较低、持续时间也比较短的情况下,ReaderWriterLock 的性能最好。多个读线程与单个写线程交替进行操作,所以读线程和写线程都不会长时间阻止。(http://msdn2.microsoft.com/zh-cn/library/system.threading.readerwriterlock(VS.80).aspx)

    至此这个 在线用户类 的整体轮廓也出来了,其主要就是对 泛型集合 Dictionary 的各种操作
    构造一个定时器,默认为每30分钟更新一下在线用户(清除不在线的 其具体的我也还说不出来 始终学得太少了 哈哈)

    说了很多废话,来简单看下怎么调用,其实 FrameWorkLogin.cs 中已经有很多例子了,
    比如 检测在线列表(checkOnline)中获取 用户信息
    OnlineUser<int> ou =   FrameWorkPermission.UserOnlineList.GetValue(U_LoginName);
    OnlineUser<int> ou 与 用户基础类 public class OnlineUser<TKey>相呼应,此处 <int>ou 则表名ou为整型,如果是常规的 int ou 则会有个装箱过程,根据 FrameWorkPermission.UserOnlineList 跳到 文件 FrameWorkPermission.cs 看到
    public static CacheOnline<int, OnlineUser<int>> UserOnlineList = null;
    CacheOnline<int, OnlineUser<int>> 则与public class CacheOnline<TKey, TValue>向呼应 这里取出的值都为整型(根据用户名获取用户信息),

    文章来自:http://www.cnblogs.com/zgqys1980/archive/2010/08/20/1804798.html

  • 相关阅读:
    分段随机实践—模拟线上流量
    基于docker的分布式性能测试框架功能验证(二)
    将博客搬家至CSDN
    考研机试 98.棋盘游戏
    考研机试 100.路径打印
    考研机试 102.计算表达式
    考研机试 97.数字反转
    考研机试 90.简单密码
    考研机试 87.鸡兔同笼
    考研机试 79.浮点数加法
  • 原文地址:https://www.cnblogs.com/xtt321/p/3657095.html
Copyright © 2011-2022 走看看