我正在建立一个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
答案 0 :(得分:21)
您需要在应用程序范围内的Set<User>
中收集所有登录用户。只需挂钩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);
}
如果您在会话中存储已登录的用户,那么您希望在会话销毁时添加另一个挂钩,以便在任何已登录的用户上发出注销。我不确定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)