2010-07-17 122 views
8

我正在grails中构建一个社区网站(使用Apache Shiro进行安全和身份验证系统),我想实现“谁在线?”功能。如何在Grails或Java应用程序中轻松实现“谁在线”?

此网址http://cksource.com/forums/viewonline.php(请参阅下面的快照,如果您没有访问此Url)给出了我想达到的一个例子。

我怎样才能以最简单的方式做到这一点? Grails或Java中是否有任何现有的解决方案?

谢谢。

快照:Snapshot of Who is online page http://www.freeimagehosting.net/uploads/th.2de8468a86.png或在这里看到:http://www.freeimagehosting.net/image.php?2de8468a86.png

+0

此URL需要登录,所以它是无用的人谁是不能或不会在该网站上注册。 – BalusC 2010-07-17 13:53:49

+0

@BalusC问题已更新 – fabien7474 2010-07-17 16:12:42

回答

21

你需要收集用户的所有信息记录在Set<User>应用范围。只需挂上loginlogout并相应地添加和删除User。基本上是:

public void login(User user) { 
    // Do your business thing and then 
    logins.add(user); 
} 

public void logout(User user) { 
    // Do your business thing and then 
    logins.remove(user); 
} 

如果你存储在会话中的登录用户,那么你想添加另一个钩子上会破坏就发出注销任何已登录的用户。我不确定Grails如何适合图片,但是在Java Servlet API中进行交流时,您希望使用HttpSessionListener#sessionDestroyed()

public void sessionDestroyed(HttpSessionEvent event) { 
    User user = (User) event.getSession().getAttribute("user"); 
    if (user != null) { 
     Set<User> logins = (Set<User>) event.getSession().getServletContext().getAttribute("logins"); 
     logins.remove(user); 
    } 
} 

你也可以让User模型实现HttpSessionBindingListener。只要User实例被放入会话中或从中删除(这也会在会话销毁时发生),将自动调用已实现的方法。

public class User implements HttpSessionBindingListener { 

    @Override 
    public void valueBound(HttpSessionBindingEvent event) { 
     Set<User> logins = (Set<User>) event.getSession().getServletContext().getAttribute("logins"); 
     logins.add(this); 
    } 

    @Override 
    public void valueUnbound(HttpSessionBindingEvent event) { 
     Set<User> logins = (Set<User>) event.getSession().getServletContext().getAttribute("logins"); 
     logins.remove(this); 
    } 

    // @Override equals() and hashCode() as well! 

} 
+0

也许还需要添加租约并在用户操作时对其进行刷新,以便在没有正确注销的情况下过滤掉非活动会话。 – 2010-07-17 14:53:48

+0

如果用户不明确注销但只关闭浏览器会怎么样? – 2010-07-17 15:19:38

+0

@Partly和@Burt:只需在最后一段中描述的servletcontainer管理的会话销毁就足够了。 – BalusC 2010-07-17 16:01:09

相关问题