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

Posted

技术标签:

【中文标题】如何在 Grails 或 Java Application 中轻松实现“谁在线”?【英文标题】:How to easily implement "who is online" in Grails or 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 问题已更新 【参考方案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】:

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

【讨论】:

谢谢斯特凡。但是,您所指的线程是关于 Spring Security 的,不幸的是我正在使用 Shiro。 嗨 Fabien,我没有仔细阅读 - 我发布的链接仅适用于 acegi。

以上是关于如何在 Grails 或 Java Application 中轻松实现“谁在线”?的主要内容,如果未能解决你的问题,请参考以下文章

在没有 SPSS 许可证的情况下从 Python、Java(groovy/grails)或 C++ 应用程序访问 SPSS 数据?

如何设置永远记住我或登录grails?

在 grails 应用程序后面使用 Python 或 C

您如何在 grails 2.3 中测试服务或控制器方法

配置gsp网页后如何编译grails程序?

如何在 Grails 应用程序和 Java 应用程序之间共享 Spring Security 类?