Home Classroom ICEfaces ICEfaces – Part 3

ICEfaces – Part 3

1184

Ajax Push with ICEfaces
Welcome back to another article on ICEfaces. This time, you are going to learn how to build a simple application with Ajax Push.

 

What is Ajax Push?

Ajax Push is a powerful feature in ICEfaces and it is a way of pushing presentation changes to the client browser based on server-side events. This means that the server can decide when to refresh the client user interface based on dynamic state changes.

So, what is interesting here is that Ajax Push enables real-time collaborative features. When multiple users are interacting with the same application, each user can be instantly aware of each others actions.

Ajax Push is also known as “Server-initiated Rendering”.

 

How it works?

ICEfaces Ajax Push is based on the concept of HTTP protocol inversion, which uses the technique of holding an open request from the browser, and responding to that request when something is available to be pushed.

Following diagram from www.icefaces.org shows the mechanism in Ajax Push.

 

  1. ICEfaces application initially makes a blocking request to server.
  2. The state of the application is changed and the application requests to render.
  3. JSF Component Tree is created.
  4. Server DOM changes are identified.
  5. Incremental update is sent back to the client browser via Ajax Bridge.
  6. Application makes another blocking request.
  7. Incremental update is applied to client DOM.

Let’s see how to make use of this mechanism.

 

APIs for Ajax Push

There are three key elements to the Ajax Push.

  • Render Manager – This is an application scoped managed bean to coordinate all render requests. This is also used to register render groups.

 

 

  • Render Group – A render group manages several Renderables (clients) that will receive same push updates. Types of render groups are: on-demand, interval and delay.

 

 

  • Renderable – Any request or session scoped managed bean implementing Renderable interface can be added to render group and push updates.

 

 

ICEfaces framework provides two different APIs for us to use server-initiated rendering in our application.

  1. RenderManager – The RenderManager API is a very powerful API, which provides better control over Ajax Push requests. This API make use of above mentioned key elements and there are several steps to configure.
  2. SessionRenderer – The SessionRenderer API is the most easiest API to use as it is designed to make use of Ajax Push with least effort. Actually the RenderManager API is used inside this API.

I am explaining only SessionRenderer API in this article and other API will be explained in a later article.

 

Sample application using the SessionRenderer API

Let’s use the SessionRenderer API to create a very simple chat application, which will be similar to an IRC (Internet Relay Chat) client.

The application will consist of two inputs. One input will be used to enter the user name and the other input will be the chat message. The command button “Send”, will add the message to application scoped list and list of messages will be displayed in the same page.

Here we are using a list in application scoped managed bean as every user connected should be able to see the message. When a message is added, we use SessionRenderer API to update message list in all users.

In my last article, I created a sample application using Eclipse IDE. This time we will extend the same application to meet our requirements.

1. First we will create the Application Scoped Managed Bean. Create the bean in the same way we created the managed bean in last article. Remember to select “application” as the scope.

Following is the code.

package view;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

public class ApplicationBean {

private List<String> messagesList;

public ApplicationBean() {

messagesList = Collections.synchronizedList(new ArrayList<String>());

}

public List<String> getMessagesList() {

return messagesList;

}

}

 

This bean contains the list of messages. I created a synchronized list to avoid any concurrency issues.

Only one instance of this bean will be created for the application.

 

2. Following is the changed code for ManagedBean.java. (The request scoped managed bean).

 

package view;

import java.text.MessageFormat;

import javax.faces.event.ActionEvent;

import com.icesoft.faces.async.render.SessionRenderer;

public class ManagedBean {

private String name;

private String message;

private ApplicationBean applicationBean;

public ManagedBean() {

SessionRenderer.addCurrentSession(“chat”);

}

public void send(ActionEvent event) {

applicationBean.getMessagesList().add(

MessageFormat.format(“{0}: {1}”, name, message));

SessionRenderer.render(“chat”);

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getMessage() {

return message;

}

public void setMessage(String message) {

this.message = message;

}

public void setApplicationBean(ApplicationBean applicationBean) {

this.applicationBean = applicationBean;

}

}

 

This bean has properties to store name and message.

When using the SessionRenderer API, the we need to add the current session to a named group.

Therefore in constructor, we call SessionRenderer.addCurrentSession(String groupName) method.

Render groups are maintained using unique names and here we used “chat” as the group name. Then an update related to “chat” group is pushed via SessionRenderer.render(“chat”) method call.

Also note that the group for current session can be removed from SessionRenderer.removeCurrentSession(String groupName) method.

 

3. Defining managed beans. Open faces-config.xml. You can select “Source” tab in Faces Configuration Editor.

 

?xml version=“1.0″ encoding=“UTF-8″?>

<faces-config

xmlns=“http://java.sun.com/xml/ns/javaee”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=“http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd”

version=“1.2″>

<application>

<view-handler>com.icesoft.faces.facelets.D2DFaceletViewHandler</view-handler>

</application>

<managed-bean>

<managed-bean-name>managedBean</managed-bean-name>

<managed-bean-class>view.ManagedBean</managed-bean-class>

<managed-bean-scope>request</managed-bean-scope>

<managed-property>

<property-name>applicationBean</property-name>

<value>#{applicationBean}</value>

</managed-property>

</managed-bean>

<managed-bean>

<managed-bean-name>applicationBean</managed-bean-name>

<managed-bean-class>view.ApplicationBean</managed-bean-class>

<managed-bean-scope>application</managed-bean-scope>

</managed-bean>

</faces-config>

You can see that “applicationBean” is injected to “managedBean” by using <managed-property> tag.

4. The ICEfacesPage1.xhtml file

<?xml version=“1.0″ encoding=“UTF-8″?>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=“http://www.w3.org/1999/xhtml”

xmlns:ui=“http://java.sun.com/jsf/facelets”

xmlns:f=“http://java.sun.com/jsf/core”

xmlns:h=“http://java.sun.com/jsf/html”

xmlns:ice=“http://www.icesoft.com/icefaces/component”>

<head>

<title><ui:insert name=“title”>Ajax Push Demo</ui:insert></title>

</head>

<body>

<div id=“header”></div>

<div id=“content”>

<ice:form>

<ice:panelGroup>

<ice:outputLabel value=“Name:” for=“txtName”></ice:outputLabel>

<ice:inputText id=“txtName” value=“#{managedBean.name}”></ice:inputText>

</ice:panelGroup>

<ice:panelGroup>

<ice:outputLabel value=“Message:” for=“txtMsg”></ice:outputLabel>

<ice:inputText id=“txtMsg” value=“#{managedBean.message}”></ice:inputText>

<ice:commandButton value=“Send” actionListener=“#{managedBean.send}”></ice:commandButton>

</ice:panelGroup>

<ice:panelSeries id=“pngMsg” value=“#{applicationBean.messagesList}”

var=“msg”>

<ice:outputText id=“otxtMsg” value=“#{msg}”

style=“display: block; border-bottom: 1px dotted blue;”>

</ice:outputText>

</ice:panelSeries>

</ice:form>

</div>

</body>

</html>

There are two inputs to get the Name and Message.

PanelSeries component is used to display the list of messages. This component is used to iterate over a collection of objects. In this example, we iterate all messages in applicationBean and display using outputText component.

Running the application

From Eclipse IDE, run the application. To demonstrate the collaborative features, we will open the application in two different browsers. Running the application in different browsers will create different sessions.

I will use Mozilla Firefox and Google Chrome to demonstrate the application.

In both browsers, enter name, message and click on “Send”. Keep the browsers side by side to see how the message you entered in one browser appear in other browser.

 

Conclusion

I only showed you the basics of Ajax Push, but you saw how easy to use this feature in an ICEfaces application. Every hard work has been done by ICEfaces framework for us to make things easier to use server initiated rendering.

In next article, I will show you how to use the RenderManager API for this same application.

Please send your questions or suggestions to chrishantha@gmail.com

 

Resources

 

Comments

comments

Isuru Perera is a senior software engineer at wso2. He is a graduate at Informatics Institute of Technology (IIT), Sri Lanka where he completed his BSc Honours Software Engineering course offered by University of Westminster, United Kingdom. LinkedIn Profile: http://www.linkedin.com/in/chrishantha

NO COMMENTS

Leave a Reply