【问题标题】:How to easily implement "who is online" in Grails or Java Application?如何在 Grails 或 Java Application 中轻松实现“谁在线”?
【发布时间】:2011-03-17 08:19:15
【问题描述】:

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

此 url 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

【问题讨论】:

  • 此 URL 需要登录,因此对于没有或不会在该站点上注册的任何人来说都是无用的。
  • @BalusC 问题已更新

标签: java grails grails-plugin shiro


【解决方案1】:

您需要在 application 范围内的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!

}

【讨论】:

  • 也许还添加一个租约并在用户操作时刷新它,以便在没有正确注销的情况下过滤掉非活动会话。
  • 如果用户没有明确退出而只是关闭浏览器怎么办?
  • @Partly 和 @Burt:如上一段所述,只需挂钩 servletcontainer-managed session destroy 就足够了。
  • @BalusC。谢谢您的回答。但是,这对于启用“记住我”cookie 的回访用户不起作用,对吧?
  • 如果 Web 服务器正在序列化和恢复会话,则此解决方案在服务器重新启动后不起作用。仍在寻找解决方法。
【解决方案2】:

【讨论】:

  • 谢谢斯特凡。但是,您所指的线程是关于 Spring Security 的,不幸的是我正在使用 Shiro。
  • 嗨 Fabien,我没有仔细阅读 - 我发布的链接仅适用于 acegi。
猜你喜欢
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多