« Back

Show live or logged in users

General Blogs January 5, 2018 By Neha Goyal

This blog is for creating an interface which will show number of live users and some other details.

First of all create a portlet which will provide interface and then create a hook within the portlet.Below link willl help to create hook in portlet.



Add below line of code in portlet view.jsp

<%@page import="com.liferay.portal.service.UserLocalServiceUtil"%>
<%@page import="com.liferay.portal.model.User"%>
<%@page import="java.util.Iterator"%>
<%@page import="com.services.loggedinuser.LoggedInUsers"%>
<%@page import="java.util.Set"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
table {
    font-family: arial, sans-serif;
    border-collapse: collapse;
    width: 100%;
td, th {
    border: 1px solid #dddddd;
    text-align: left;
    padding: 8px;
th {
background-color: #e1e1e1;
tr:nth-child(even) {
    background-color: #eee;
<div style="border:1px solid #ccc;padding:5pt;">
<b>Total number of Live Users : </b>
Set<Long> users_set = LoggedInUsers.loggedInUsers();
<b><%=users_set.size() %></b><br/>
<tr><th>User Id</th><th>Screen Name</th><th>Full Name</th><th>IP Address</th><th>Login Date</th></tr>
Iterator<Long> it = users_set.iterator();
long user_id = it.next();
User user = UserLocalServiceUtil.getUser(user_id);
String fullName = user.getFullName();
String ipAddress = user.getLastLoginIP();
String screenname = user.getScreenName();
String loginDate = user.getLoginDate().toString();
<td><%=user_id %></td>
<td><%=screenname %></td>
<td><%= fullName%></td>
<td><%=ipAddress %></td>
<td><%=loginDate %></td>
Now it s time to work on hook which we have create and which will tell about live users.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.2.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_2_0.dtd">
Create LoginPostAction and SessionDestroyAction class.
package com.services.loggedinuser;
import com.liferay.portal.kernel.events.Action;
import com.liferay.portal.util.PortalUtil;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginPostAction extends Action {
public void run(HttpServletRequest request, HttpServletResponse response) {
long userId = PortalUtil.getUserId(request);
System.out.println("Logged in user :"+userId);
package com.services.loggedinuser;
import com.liferay.portal.kernel.events.SessionAction;
import com.liferay.portal.kernel.util.WebKeys;
import javax.servlet.http.HttpSession;
public class SessionDestroyAction extends SessionAction{
public void run(HttpSession session) {
Long userId = (Long) session.getAttribute(WebKeys.USER_ID);
System.out.println("Log out user :"+userId);
Also create one model object for live users.
package com.services.loggedinuser;
import java.util.HashSet;
import java.util.Set;
public class LoggedInUsers {
private static Set<Long> users = new HashSet<Long>();
public static void addUser(long userId) {
public static void clearUsers() {
public static void removeUser(long userId) {
public static int countUsers() {
return users.size();
public static boolean isLogged(long userId) {
return users.contains(userId);
public static Set<Long> loggedInUsers(){
return users;
Threaded Replies Author Date
It is important to note that the list you get... David H Nebinger February 16, 2018 2:12 PM
Thanks David for the detailed feedback. Could... Neha Goyal March 5, 2018 11:06 PM
The browser close (or general disconnect from... David H Nebinger March 6, 2018 6:29 AM

It is important to note that the list you get will likely never be 100% accurate. For example, if a user logs in and just closes the browser, they will show as logged in, even when they are not, until their session expires.

Also this code will never work in a cluster since it is based on per-node session creation/destruction. The only list you'll get is the list from the node you happen to connect to.
Posted on 2/16/18 2:12 PM.
Thanks David for the detailed feedback. Could you mind to share your thought how i can resolve above issues.
I would be really thankful to you.

Posted on 3/5/18 11:06 PM in reply to David H Nebinger.
The browser close (or general disconnect from internet) issue you can use a short session with auto-extend enabled. That shortens the amount of time a user would show as logged in, even though they are not. Note that this cannot be eliminated because, if you just close the browser, there is absolutely nothing you can do about it.

For the cluster, you could message the events around the cluster to notify the other nodes. This has two issues, though. First it magnifies the session timeout issue above (you see invalid sessions from all nodes instead of just one), and second you may need to resolve cases where users are on multiple nodes (either because they are logged in using multiple devices or because you are not using sticky sessions).

These are not issues for Liferay, per se, these are issues that all internet systems struggle with. Closing the browser is simply not solvable using today's browser/http technology. The cluster issue can be resolved, but will take additional effort on your part to make it happen. But then you need to ask yourself if solving this problem actually gives you anything worthwhile or whether it is just throwing money away.
Posted on 3/6/18 6:29 AM in reply to Neha Goyal.