客户访问限制管理器

来源:互联网 发布:mud编程 编辑:程序博客网 时间:2024/05/16 01:43

    前段时间开发短信收发系统,遇到一个问题,就是有n个对象都可以通过Mobile对象发短信,但同一时刻只允许一个对象进行操作。所以设计了一个客户限制管理器的对象来解决,但由于种种原因没有用到实际系统中。后来经过仔细考虑,发现它不仅可以用于端口的管理,还可用于其他需要针对客户访问数量进行限制的各种服务中去。----这里的“客户”是指要操作该管理器的对象

 

  1. /**
  2.  * 客户限制管理器的抽象类<br>
  3.  * 此抽象类实现了对客户访问的限制,当一个客户访问该服务时,可以通过halt(long guestid)方法阻止其他客户进行
  4.  * 访问,防止多个客户同时访问产生的冲突。例如:对通讯端口的访问等。<br>
  5.  * 
  6.  * @author none
  7.  * 
  8.  */
  9. public abstract class GuestManager {
  10.     /**
  11.      * 时间:一分钟
  12.      */
  13.     protected static final long ONE_MINUTE = 60L * 1000L;
  14.     
  15.     /**
  16.      * 时间:一小时
  17.      */
  18.     protected static final long ONE_HOUR = 60L * ONE_MINUTE;
  19.     /**
  20.      * 自动清理客户记录的间隔时间
  21.      */
  22.     private long cleanInterval;
  23.     /**
  24.      * 客户记录<客户标识,最近访问时间>
  25.      */
  26.     private Hashtable<String, String> guests;
  27.     /**
  28.      * 当前限制的客户
  29.      */
  30.     private long limitGuest;
  31.     /**
  32.      * 自动清除过期客户的线程
  33.      */
  34.     private Thread autoCleanThread;
  35.     /**
  36.      * 客户注册
  37.      * 
  38.      * @return 返回分配给客户端的唯一标识,如果注册失败,返回-1
  39.      */
  40.     public long login() {
  41.         long guestid = -1L;
  42.         // 增加客户记录
  43.         Hashtable<String, String> guests = getGuests();
  44.         if (guests != null) {
  45.             guestid = System.currentTimeMillis();
  46.             guests.put("" + guestid, "" + guestid);
  47.             update(guestid);
  48.             // if (guests.size() == 1)
  49.             // connect();
  50.         }
  51.         return guestid;
  52.     }
  53.     /**
  54.      * 检查客户是否已经注册
  55.      * 
  56.      * @param guestid
  57.      *            客户标识
  58.      * @return 如果客户已经注册返回true,否则返回false
  59.      */
  60.     public boolean isLogin(long guestid) {
  61.         boolean flag = false;
  62.         if (guestid > 0) {
  63.             Hashtable<String, String> guests = getGuests();
  64.             if (guests != null)
  65.                 flag = guests.containsKey("" + guestid);
  66.             if (flag)
  67.                 update(guestid);
  68.         }// end if (guestid > 0)
  69.         return flag;
  70.     }
  71.     /**
  72.      * 注销客户<br>
  73.      * 如果仍有其他客户在使用此对象,则仅仅注销guestid客户,否则调用disconnect()方法关闭连接。
  74.      * 
  75.      * @param guestid
  76.      *            客户标识
  77.      * @return 返回是否成功注销
  78.      */
  79.     public void logout(long guestid) {
  80.         Hashtable<String, String> guests = getGuests();
  81.         if (guests != null) {
  82.             if (guestid > 0 && guests.containsKey("" + guestid)) {
  83.                 guests.remove("" + guestid);
  84.             }// end if (guestid > 0 && getGuests().containsKey("" +
  85.             // guestid))
  86.         }// end if (guests != null)
  87.     }
  88.     /**
  89.      * 限制<br>
  90.      * 如果某一客户调用了该方法,那么其他客户将无法访问,直至该客户调用resume()释放。
  91.      * 
  92.      * @param guestid
  93.      *            中断标识
  94.      * @return 返回是否成功中断
  95.      */
  96.     public boolean limit(long guestid) {
  97.         boolean flag = false;
  98.         if (isLogin(guestid)) {
  99.             update(guestid);
  100.             if (isLimit(guestid))
  101.                 return flag;
  102.             limitGuest = guestid;
  103.             flag = true;
  104.         }// end if (isLogin(guestid))
  105.         return flag;
  106.     }
  107.     /**
  108.      * 释放
  109.      * 
  110.      * @param guestid
  111.      *            客户标识
  112.      * @return 返回是否释放成功
  113.      */
  114.     public boolean resume(long guestid) {
  115.         boolean flag = false;
  116.         if (isLogin(guestid)) {
  117.             update(guestid);
  118.             if (limitGuest == guestid) {
  119.                 limitGuest = -1L;
  120.             }// end if(haltGuest == guestid)
  121.             flag = !isLimit();
  122.         }
  123.         return flag;
  124.     }
  125.     /**
  126.      * 是否限制其他客户调用
  127.      * 
  128.      * @return 返回是否限制其他客户调用
  129.      */
  130.     protected boolean isLimit() {
  131.         boolean flag = false;
  132.         if (limitGuest > 0) {
  133.             long lasttime = Long.parseLong((getGuests().get(
  134.                     "" + limitGuest)));
  135.             if (lasttime > 0) {
  136.                 // 如果10分钟内无响应,则注释放该客户的中断
  137.                 long time = System.currentTimeMillis() - 10L
  138.                         * ONE_MINUTE;
  139.                 if (time < lasttime)
  140.                     flag = true;
  141.                 else
  142.                     limitGuest = -1;
  143.             }
  144.         }// end if(this.id <= 0)
  145.         return flag;
  146.     }
  147.     /**
  148.      * 该客户是否被限制访问
  149.      * 
  150.      * @param haltId
  151.      *            客户标识
  152.      * @return 返回true表示禁止访问,false表示可以访问
  153.      */
  154.     public boolean isLimit(long guestid) {
  155.         boolean flag = true;
  156.         if (isLogin(guestid)) {
  157.             update(guestid);
  158.             flag = isLimit();
  159.             if (flag) {
  160.                 if (guestid > 0 && limitGuest == guestid)
  161.                     flag = false;
  162.             }// end if(flag)
  163.         }
  164.         return flag;
  165.     }
  166.     /**
  167.      * 取得当前限制客户的标识(该标识是该管理器为客户分配的一个唯一标识)
  168.      * 
  169.      * @return 返回当前限制客户的标识
  170.      */
  171.     protected long getLimitGuest() {
  172.         return limitGuest;
  173.     }
  174.     /**
  175.      * 更新客户最近使用时间<br>
  176.      * 
  177.      * @param guestid
  178.      *            客户标识
  179.      */
  180.     protected void update(long guestid) {
  181.         runThread();
  182.         Hashtable<String, String> guests = getGuests();
  183.         if (guests != null && guests.containsKey("" + guestid))
  184.             guests.put("" + guestid, ""
  185.                     + System.currentTimeMillis());
  186.     }
  187.     /**
  188.      * 运行监听线程
  189.      */
  190.     protected void runThread() {
  191.         // 客户自动清理线程
  192.         if (autoCleanThread != null && !autoCleanThread.isAlive())
  193.             autoCleanThread = null;
  194.         if (autoCleanThread == null) {
  195.             autoCleanThread = new AutoCleanThread();
  196.             autoCleanThread.start();
  197.         }// end if (autoCleanThread == null)
  198.     }
  199.     /**
  200.      * 设置自动清理客户记录的间隔时间
  201.      * 
  202.      * @param time
  203.      *            间隔时间(毫秒)
  204.      */
  205.     public void setCleanInterval(long time) {
  206.         if (time > 0)
  207.             cleanInterval = time;
  208.     }
  209.     /**
  210.      * 取得自动清理客户记录的间隔时间
  211.      * 
  212.      * @return 返回自动清理客户记录的间隔时间(毫秒)
  213.      */
  214.     public long getCleanInterval() {
  215.         return cleanInterval;
  216.     }
  217.     /**
  218.      * 取得客户记录
  219.      * 
  220.      * @return 返回客户记录。格式为<客户标识,最近访问时间>
  221.      */
  222.     protected Hashtable<String, String> getGuests() {
  223.         if (guests == null)
  224.             guests = new Hashtable<String, String>();
  225.         return guests;
  226.     }
  227.     /**
  228.      * 输出错误信息
  229.      * 
  230.      * @param err
  231.      */
  232.     public abstract void trace(String err);
  233.     /**
  234.      * 自动清除超时的客户端的线程
  235.      * 
  236.      */
  237.     private class AutoCleanThread extends Thread {
  238.         public void run() {
  239.             trace("AutoCleanThread thread start runing...");
  240.             long interval = ONE_HOUR / 4L;
  241.             if (getCleanInterval() > 0)
  242.                 interval = getCleanInterval();
  243.             
  244.             while (autoCleanThread == this && getGuests().size() > 0) {
  245.                 long time = System.currentTimeMillis()
  246.                         - ONE_HOUR / 2L;
  247.                 Enumeration<?> keys = getGuests().keys();
  248.                 while (keys.hasMoreElements()) {
  249.                     String key = (String) keys.nextElement();
  250.                     if (key != null) {
  251.                         long lasttime = Long.parseLong(getGuests()
  252.                                 .get(key));
  253.                         if (time > lasttime)
  254.                             // 超时
  255.                             getGuests().remove(key);
  256.                     }// end if (key != null)
  257.                 }// end while (keys.hasMoreElements())
  258.                 try {
  259.                     Thread.sleep(interval);
  260.                 } catch (InterruptedException e) {
  261.                     e.printStackTrace();
  262.                     trace("error - " + e.toString());
  263.                 }
  264.             }// end while (mobiles != null && mobiles.size() > 0)
  265.             trace("AutoCleanThread thread end...");
  266.         }
  267.     }
  268. }

 

  1. /**
  2.  * 通讯端口的客户端限制管理器的抽象类<br>
  3.  * 该类继承自GuestManager类,增加了connect()、disconnect()等方法
  4.  * 
  5.  * @author none
  6.  *
  7.  */
  8. public abstract class PortGuestManager extends GuestManager {
  9.     
  10.     /**
  11.      * 连接
  12.      * 
  13.      * @return 返回是否连接成功
  14.      */
  15.     protected abstract boolean connect();
  16.     /**
  17.      * 断开
  18.      * 
  19.      * @return 返回是否断开成功
  20.      */
  21.     protected abstract boolean disconnect();
  22.     /**
  23.      * 是否已经连接
  24.      * 
  25.      * @return 返回端口是否已经连接
  26.      */
  27.     protected abstract boolean isConnected();
  28.     
  29.     public long login() {
  30.         long guestid = -1L;
  31.         if (!isConnected())
  32.             connect();
  33.         if (isConnected())
  34.             guestid = super.login();
  35.         
  36.         return guestid;
  37.     }
  38.     public boolean limit(long guestid) {
  39.         boolean flag = false;
  40.         if (isConnected())
  41.             flag = super.limit(guestid);
  42.         return flag;
  43.     }
  44.     
  45.     public void logout(long guestid) {
  46.         super.logout(guestid);
  47.         
  48.         Hashtable<String, String> guests = getGuests();
  49.         if (guests != null)
  50.             if (guests.size() <= 0)
  51.                 disconnect();
  52.     }
  53.     
  54.     public boolean isLimit(long guestid) {
  55.         boolean flag = true;
  56.         if (isConnected())
  57.             flag = super.isLimit(guestid);
  58.         return flag;
  59.     }
  60. }
原创粉丝点击