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

fab*_*474 8 java grails grails-plugin shiro

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

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

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

谢谢.

快照:Who的快照在线页面http://www.freeimagehosting.net/uploads/th.2de8468a86.png或在此处查看:http://www.freeimagehosting.net/image.php?2de8468a86.png

Bal*_*usC 21

您需要Set<User>应用程序范围内收集a 中的所有登录用户.只要勾上login,并logout和添加和删除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);
}
Run Code Online (Sandbox Code Playgroud)

如果您将登录的用户存储在会话中,那么您希望在会话销毁时添加另一个挂钩,以便在任何已登录的用户上发出注销.我不确定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);
    }
}
Run Code Online (Sandbox Code Playgroud)

您也可以让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!

}
Run Code Online (Sandbox Code Playgroud)

  • 如果Web服务器正在序列化并还原会话,则此解决方案在服务器重新启动时不起作用.仍在寻找解决方法. (2认同)