如何在Grails或Java Application中轻松实现“谁在线”?

时间:2010-07-17 13:34:16

标签: java grails grails-plugin shiro

我正在建立一个grails社区网站(使用Apache Shiro进行安全和身份验证系统),我想实现“谁在线?”这一功能。

此网址http://cksource.com/forums/viewonline.php(如果您没有访问此网址,请参阅下面的快照)举例说明了我希望实现的目标。

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

谢谢。

快照:Snapshot of Who is online page http://www.freeimagehosting.net/uploads/th.2de8468a86.png或点击此处:http://www.freeimagehosting.net/image.php?2de8468a86.png

2 个答案:

答案 0 :(得分: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!

}

答案 1 :(得分:2)