/* ==================================================================
* Created [2009-4-27 下午11:32:55] by Jon.King
* ==================================================================
* TSS
* ==================================================================
* mailTo:jinpujun@hotmail.com
* Copyright (c) Jon.King, 2009-2012
* ==================================================================
*/
package com.jinhe.tss.core.sso.online.cache;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.jinhe.tss.core.sso.online.IOnlineUserManager;
import com.jinhe.tss.core.sso.online.OnlineUser;
/**
* <p> CacheOnlineUserManager.java </p>
*
*<br/> Cache在线用户库:
*<br/> 包含了 3个Map:
*<br/> 1、tokenMap : key:token , value:Set[OnlineUser]
*<br/> 2、sessionIdMap : key:appCode+"_"+sessionId, value:OnlineUser(含有token)
*<br/> 3、usersMap : key:userId , value:userName 用来统计在线用户信息
*
*<br/> 一个令牌可以在多个应用中使用,所以会有多个在线用户信息。
*<br/> 而一个session(对应一个打开状态的页面)在一个应用里只有一个在线用户信息
*<br/>(但有可能多个用户在这页面登陆过, 如此sessionIdMap只保存最后一个登陆的用户),
*<br/> 页面刷新时sessionId不变,但如果超时后刷新重新登陆后(或者换个用户登陆),token将会发生变化(将重新生成)。
*<br/>
*
*/
public class CacheOnlineUserManager implements IOnlineUserManager {
protected Map<String, Set<OnlineUser>> tokenMap = new HashMap<String, Set<OnlineUser>>();
protected Map<String, OnlineUser> sessionIdMap = new HashMap<String, OnlineUser>();
protected Map<Long, String> usersMap = new HashMap<Long, String>();
public String logout(String appCode, String sessionId) {
//删除当前sessionId在当前应用中登陆后产生的在线用户信息
OnlineUser userInfo = (OnlineUser) sessionIdMap.remove(getSessionIdMapKey(appCode, sessionId));
if (userInfo == null) return null;
String token = userInfo.getToken();
Set<OnlineUser> userInfos = tokenMap.get(token);
userInfos.remove(userInfo); //删除令牌在当前应用下的 在线用户信息,不包含其它的应用。
// 判断Token是否已经退出了所有应用,是的话移除此Token
if (userInfos.size() == 0) {
tokenMap.remove(token);
usersMap.remove(userInfo.getUserId());
}
userInfo = null;
userInfos = null;
return token;
}
public Set<OnlineUser> getOnlineUsersByToken(String token) {
return tokenMap.get(token);
}
public boolean isOnline(String token) {
return tokenMap.containsKey(token);
}
public void register(String token, String appCode, String sessionId, Long userId, String userName) {
OnlineUser user = new OnlineUser(userId, appCode, sessionId, token);
/* onlineUsers 用来退出时判断当前Token是不是已经退出了所有应用,是的话将token从tokenMap中移除。 */
Set<OnlineUser> onlineUsers = tokenMap.get(token);
/* 判断同一个令牌是否已经注册过,如果没有则初始化一个 onlineUsers */
if (onlineUsers == null) {
tokenMap.put(token, onlineUsers = new HashSet<OnlineUser>());
}
/*
* 注意此处用的是Set:如果是同一个令牌在同一个应用里再次注册,则user相同,add到Set将会覆盖原来的;
* 否则将令牌在当前应用注册。
*/
onlineUsers.add(user);
sessionIdMap.put(getSessionIdMapKey(appCode, sessionId), user);
usersMap.put(userId, userName);
}
/**
* <p>
* 根据当前应用Code和当前SessionId生成SessionIdMap的key
* </p>
* @param appCode
* @param sessionId
* @return
*/
protected String getSessionIdMapKey(String appCode, String sessionId) {
return appCode + "_" + sessionId;
}
public Collection<String> getOnlineUserNames() {
return usersMap.values();
}
}