当前位置: 代码迷 >> Java Web开发 >> 关于在线用户的实现,同一帐号登录有关问题
  详细解决方案

关于在线用户的实现,同一帐号登录有关问题

热度:4123   发布时间:2013-02-25 21:16:58.0
关于在线用户的实现,同一帐号登录问题
public class OnlineCounterListener implements HttpSessionBindingListener {
private OnlineUser newUser=null; //OnlineUser是用户类
 
/**
* Constructor for OnlineCounterListener.
*/
public OnlineCounterListener() {
newUser = new OnlineUser();


@Override
public void valueBound(HttpSessionBindingEvent e) {
User user = (User)e.getSession().getAttribute("userInfo"); 
newUser.setUser(user);
try {
if(isInList(user))
newUser.updateOnline();
}
catch (Exception ex) {
}
//System.out.println("用户"+e.getSession().getAttribute("ScmLogin")+"上限");

}
@Override
public void valueUnbound(HttpSessionBindingEvent e) {
//User user = (User)e.getSession().getAttribute("userInfo");
// newUser.setUser(user);
try {
newUser.updateUnline();
}
catch (Exception ex) {
}

}
public boolean isInList(User user){
List list = OnlineUser.getList();
if(list.size()>0){  
for(int i=0;i<list.size();i++){  
User myLogin = (User)list.get(i);
if(user.getId()==myLogin.getId())
return false;
}
}
return true;  


这个方法可以实现在线用户,但是现在需要同一账户只能登录后一次登录的把前一次登录的顶掉,类似QQ。这个需要用到sessionId ,但是我现在这样写的不知道该怎么用sessionId ?
哪个高手出来帮帮忙。

------解决方案--------------------------------------------------------
非集群情况下,实现起来会简单些,只需要找个HashMap记录当前的账户所对应的sessionId即可。

如果发现本会话发现自己没有对应任何账户,说明已经被顶下线了。


但如果集群情况的话,那么问题会复杂很多。
------解决方案--------------------------------------------------------
意思就是:用户登录时,即建立 SessionID 与 该用户账户 之间的对应关系。

每次存在访问,就检查当前SessionID的对应关系是否存在,不存在就说明被后来登录的给覆盖了呗。
------解决方案--------------------------------------------------------
登陆的时候增加如下逻辑:
Map<String,String> sessionIdMap = (Map<String,String>)applicationContext.getAttribute("sessionIdMap ");
if(sessionIdMap == null){
 sessionIdMap = new HashMap<String,String>();
}
sessionIdMap.put(user.getUserName,request.getSession().getSessionId());
增加一个filter,逻辑如下:
Map<String,String> sessionIdMap = (Map<String,String>)applicationContext.getAttribute("sessionIdMap ");
if(sessionIdMap != null && sessionIdMap.get(user.getUserName()) != null || !request.getSession().getSessionId().equals(sessionIdMap.get(user.getUserName()))){
//此种情况重复登陆,forward到登陆页面
}else{
//此种情况正常,只有一处地方登陆dofilter(......);
}
------解决方案--------------------------------------------------------
在数据 建立一张表 保存用户ID 和状态 还有登录的sessionID,登录时间 用异步提交的时候定时去数据库中那张表,动态的更新登录时间,在定时的去根据时间验证,当用户直接关闭浏览器的时候, 你用户时间没有更新就自动删除,后者登录的时候去表中验证,存在则删除,弹出登录者(AJAX)实现。
------解决方案--------------------------------------------------------
大概思路可以这样:A登录了,保存一些信息(比如放在所有在线的人员标识放在一map);
然后B来登录了,发现与A是同一个人(即在map里面有他的标识存在了),就修改下这个用户标识(比如map对应的ip)
那当A操作时发现自己map里面的标识变了,然后就自动下线。把标识放进数据库也一样的道理吧。

不过这样做有一问题就是,因为你只是更改了A的数据,如果A不操作,那他显示的还是在线,必须有触发才能检查到数据的变化,从而做出反应。
  相关解决方案