Struts 2で「スクリーンセーバー」を使ってオンライン会員統計と重複登録防止を実現します.


(はぁ、このタイトルは長いですね.)
 
必要:
1.管理者の楽屋には、現在のオンライン訪問者数及びオンライン会員数(オンライン会員要求について詳細リストをリストする)が表示されます.
2.あるクライアントが不正に退出した後(直接ブラウザを閉じたり、電源を切ったりして)、彼はシステムを再登録します.オンライン統計で登録統計の正確性と完全性を維持します.
3.複数のクライアントが同時に一つのアカウントを使って異郷登録をすることを防止する(後で登録者が先登録者を蹴落として、先に登録者に通知してからオフラインを余儀なくさせる).
 
 
1.モニターSession Listener(web.xmlのコード略)
/**
	 *   session
	 */
	public void sessionCreated(HttpSessionEvent se) {
		OnlineStatistics.increase();
	}

	/**
	 *      session  
	 */
	public void sessionDestroyed(HttpSessionEvent se) {
		OnlineStatistics.decrease();
	}

	/**
	 *      
	 */
	public void attributeAdded(HttpSessionBindingEvent se) {
		if ("memberInfo".equals(se.getName())) {
			MemberInfo memberInfo = (MemberInfo) se.getValue();
			OnlineStatistics.addAttr(memberInfo);
			se.getSession().setMaxInactiveInterval(60 * 20);//     SEC * MINS
		}
	}

	/**
	 *       (  session   )
	 */
	public void attributeRemoved(HttpSessionBindingEvent se) {
		if ("memberInfo".equals(se.getName())) {
			MemberInfo memberInfo = (MemberInfo) se.getValue();
			OnlineStatistics.removeAttr(memberInfo);
			memberInfo = null;
		}
	}

	/**
	 *    
	 */
	public void attributeReplaced(HttpSessionBindingEvent se) {
//to be extended
	}
 
 2.統計類Online Statistics
/**
 * @author Arantam
 */
package com.farago.util;

import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import com.farago.vo.MemberInfo;

/**
 * @author Arantam
 * 
 */
@SuppressWarnings("unchecked")
public class OnlineStatistics {
	private static int count = 0;
	private static Set onlineMemberList = new HashSet();

	/**
	 *       (  )
	 */
	public static void increase() {
		count++;
	}

	/**
	 *       (  )
	 */
	public static void decrease() {
		count--;
	}

	/**
	 *       (  )
	 * 
	 * @param memberInfo
	 */
	public static void addAttr(MemberInfo memberInfo) {
		//            ,      ,         id       id    .
		Iterator itr = onlineMemberList.iterator();
		while (itr.hasNext()) {
			//           session          .  ,     ,     .
			MemberInfo temp = (MemberInfo) itr.next();
			String memberName = temp.getName();//            
			if (memberInfo.getName().equals(memberName)) {
				itr.remove();
			}
		}
		onlineMemberList.add(memberInfo);
	}

	/**
	 *       (  )
	 * 
	 * @param memberInfo
	 */
	public static void removeAttr(MemberInfo memberInfo) {
		onlineMemberList.remove(memberInfo);
	}

	/**
	 *          
	 * 
	 * @return the count
	 */
	public static int getOnlineVisitors() {
		return count - 1;//        
	}

	/**
	 *          
	 * 
	 * @return the onlineMemberList
	 */
	public static Set getOnlineMemberList() {
		return onlineMemberList;
	}

	/**
	 *                
	 * 
	 * @param memberInfo
	 * @return
	 */
	public static boolean isOld(MemberInfo memberInfo) {
		Iterator itr = onlineMemberList.iterator();
		while (itr.hasNext()) {
			MemberInfo temp = (MemberInfo) itr.next();
			String memberName = temp.getName();//            
			Date loginTime = temp.getLoginTime();//               
			if (memberInfo.getName().equals(memberName) && memberInfo.getLoginTime().before(loginTime)) {
				//                                ,   true
				return true;
			}
		}
		return false;
	}

}
 
 
3.ブロッキングコードの断片
Map sessionMap = invocation.getInvocationContext().getSession();
		if (sessionMap.get("memberInfo") != null) {
			MemberInfo memberInfo = (MemberInfo) sessionMap.get("memberInfo");

			/**
			 * 
			 */
			if (OnlineStatistics.isOld(memberInfo)) {
				sessionMap.remove("memberInfo");//   session
				faragoMessage = "   ,    [" + memberInfo.getName() + "]        ,      。          ,  !";
				ctx.put("faragoMessage", faragoMessage);
				return Action.ERROR;
			}
......
...
 
 
 
フロントでも現在のオンライン人数を表示したいなら、session Createdとsession Destroyedの方法で処理して、統計数字をServlet Conteetの中に入れて、S 2のラベルを使って直接表示してもいいです.これは便利です.
 
 
終わります
 
 
 
 
---譚剣2010-7-6