Liferay provides a feature that tracks the session activity on the client and provides the means, at a configurable interval, to display a warning that the session is about to expire. This client-side tracker relies on detecting when a request is sent to the server and adjusts its own internal timer appropriately.
One of the difficulties with the client-side session tracker is dealing with Ajax requests. Ajax requests from 3rd-party libraries are not typically detected by the tracker which can lead to the tracker issuing a warning and displaying the warning/expiration banner even though the user has been actively interacting with one or more portlets on the page. In order to help with this, Liferay provides a client-side API that libraries like ICEfaces can call when making Ajax requests to help keep the tracker notified of user activity.
However, in Liferay versions prior to 6.1.0 CE RC1 and 6.0.12 EE, the tracker and its API has bugs that prevent it from working properly in certain use cases. The following JIRAs contain additional technical details about the various fixes and changes to the APIs documented here.
The follow sections detail the Liferay.Session APIs, both before and after the main work was done to fix the various issues.
In versions of Liferay before the fix in LPS-17624 (i.e. before 6.1.0 CE RC1 and 6.0.12 EE), the Liferay.Session API provides two possible ways of notifying the client-side session tracker that something has occurred and that the timer should be reset.
The first is the extend() function. This is the most reliable mechanism but sends a separate request to the server to ensure the session is also touched on the server-side. This request is in addition to the actual Ajax request that is being made as part of the normal user-interaction:
The other is the setCookie() function which does not send a separate request to the server.
In versions of Liferay after the fixes for LPS-17624 (i.e. starting from 6.1.0 CE RC1 and 6.0.12 EE), the Liferay.Session API provides two possible ways of notifying the client-side session tracker that something has occurred and that the timer should be reset:
Just like in previous versions of Liferay, the extend() function is still supported. While it now works more reliably, the behaviour is much the same as in previous versions of Liferay in that it sends a separate request to the server. It's best to use this API when you are doing primarily client-side behaviours but still want to notify the server that the session should be kept active. It's also a good choice if you need to support a codebase across multiple versions of Liferay.
The recommended approach is to use the Liferay.Session.set() function. By accepting various parameters, this function allows the developer more control over the state and behaviour of Liferay's client-side warning system. In addition, this function does not make an additional call to the server so it's the ideal choice to use for a framework like ICEfaces where an Ajax request is already being made to the server. However, it's only available in relatively recent versions of Liferay.
To effectively use the Liferay API, we need to hook it in to the appropriate spot in ICEfaces so that with each Ajax request submitted, the client-side session tracker is notified. This depends on which version of ICEfaces is being used.
In ICEfaces 1.x, the client API for registering a callback you want called before a request is sent is:
This function is deprecated but still supported in current releases of ICEfaces for backwards compatibility.
In ICEfaces 2.x+, the client API for registering a callback you want called before a request is sent is this:
In order to notify the client-side tracker with each Ajax request, you need to do a couple of things:
There are different ways to do this depending on which version of ICEfaces and JSF you are using. With ICEfaces 2.x+ you can take advantage of some of the new features and integration points of JSF 2.0. One way to do this is to create a SystemEventListener that automatically adds the script to the markup of the portlet. The main steps to do this are:
As an example of how to do this, download the attached example project that shows one way this can be done:
Because ICEfaces 1.x uses JSF 1.2, SystemEventListener is not available so the same technique cannot be used. One alternative would be to write out the script contents from a backing using an outputText component:
However, there are other ways to get scripts into the content of a Liferay portlet. Use the one that suits your needs best.
© Copyright 2021 ICEsoft Technologies Canada Corp.