9

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

这个网址http://cksource.com/forums/viewonline.php(如果您没有访问此网址,请参阅下面的快照)给出了我想要实现的示例。

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

谢谢你。

快照:谁是在线页面的快照 http://www.freeimagehosting.net/uploads/th.2de8468a86.png或在这里查看:http ://www.freeimagehosting.net/image.php?2de8468a86.png

4

2 回答 2

23

您需要收集应用程序范围内Set<User>的所有登录用户。只需挂上并相应地添加和删除。基本上:loginlogoutUser

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模型实现HttpSessionBindingListenerUser每当将实例放入会话或从中删除时,将自动调用已实现的方法(这也将在会话销毁时发生)。

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!

}
于 2010-07-17T13:57:00.570 回答
2

这已在邮件列表中讨论过:http: //grails.1312388.n4.nabble.com/Information-about-all-logged-in-users-with-Acegi-or-SpringSecurity-in-Grails- td1372911.html

于 2010-07-17T14:17:42.577 回答