I am building a community website in grails (using Apache Shiro for security and authentication system) and I would like to implement the feature "who is online?".
This url http://cksource.com/forums/viewonline.php (see snapshot below if you do not have acess to this Url) gives an example of what I would like to achieve.
How can I do that in the most simple way? Is there any existing solution in Grails or in Java ?
Thank you.
Snapshot : Snapshot of Who is online page http://www.freeimagehosting.net/uploads/th.2de8468a86.png or see here : http://www.freeimagehosting.net/image.php?2de8468a86.png
You need to collect all logged in users in a Set<User>
in the application scope. Just hook on login
and logout
and add and remove the User
accordingly. Basically:
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);
}
If you're storing the logged-in users in the session, then you'd like to add another hook on session destroy to issue a logout on any logged-in user. I am not sure about how Grails fits in the picture, but talking in Java Servlet API, you'd like to use HttpSessionListener#sessionDestroyed()
for this.
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);
}
}
You can also just let the User
model implement HttpSessionBindingListener
. The implemented methods will be invoked automagically whenever the User
instance is been put in session or removed from it (which would also happen on session destroy).
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!
}