Showing posts with label atmosphere. Show all posts
Showing posts with label atmosphere. Show all posts

Wednesday, February 8, 2012

4 simple steps for RichFaces Push with 4.2


RichFaces Push is a pretty useful component, since it enables you do a server-side push technique (pushing content from a server to a client asynchronously). What makes this component so attractive when there are plenty of other ways to achieve this?

RichFaces is enabling application developers to build on top of push without any additional complexity.

It is enough to use only one interface (which can even be injected using CDI) on the server side. And you need only one component on the client side: <a4j:push>.

In this blog, I’m not going to show all possibilities of how to use the RichFaces Push - instead, I will show you, how to configure this component to work on your favorite container including small sample page and bean. Why?

We have simplified Push drastically along the way from 4.0 to 4.1 and we are continuing in 4.2 to make the process of setting up a project with Push as simple as possible! That’s why I’m sharing our progress with you.

Let’s start...

We will start with SimpleApp maven archetype - it doesn’t have Push configured. It assumes that you have following dependencies installed:
  • Maven 3.0.3+
  • JDK 1.6
  • your favorite editor
  • your favorite servlet container or application server

Creating the project stub

Okay, let’s create the new app based on the SimpleApp archetype:

mvn archetype:generate -DarchetypeGroupId=org.richfaces.archetypes -DarchetypeArtifactId=richfaces-archetype-simpleapp -DgroupId=my.domain -DartifactId=simplepush -Dversion=1.0-SNAPSHOT -Dpackage=my.domain -DarchetypeVersion=4.2.0.CR1


Note: RichFaces Developer Guide may help you when you get stuck with setting up environment:


We have created a stub for our application, now you can try to deploy it on your favorite container and verify basic functionality:

http://localhost:8080/simplepush/

You should see one ajaxified input and when typing, you should see appropriately updated output.

4 simple steps for Push

What are the modifications we will undertake next?
  • install Atmosphere libraries
  • register a servlet (if necessary)
  • add a managed bean with an action triggering a push event
  • add an a4j:push component to the a page

Installing Atmosphere libraries

Atmosphere is the only runtime dependency for RichFaces Push. Atmosphere enables integration with various containers and interoperability between browsers and push techniques (websockets, long-polling).

In order to install Atmosphere in your project, add following lines into your pom.xml, in the section <dependencies>:

<dependency>
    <groupId>org.atmosphere</groupId>
    <artifactId>atmosphere-runtime</artifactId>
</dependency>

Note: version of the dependency is automatically managed by importing the richfaces-bom, that’s why you don’t need to specify <dependency><version> here.

Registering PushServlet

RichFaces Push requires PushServlet registered for web application in order to connect to a container and listen for push requests.

In Servlets 3.0 and higher environments (JBoss AS 6 and 7, Tomcat 7, GlassFish 3, etc.), the servlet will be registered automatically by including RichFaces Core libraries on classpath.

However in Servlets 2.5 and lower, servlet needs to be registered manually in web.xml:

<!-- Push Servlet - listens for user sessions -->
<servlet>
    <servlet-name>Push Servlet</servlet-name>
    <servlet-class>org.richfaces.webapp.PushServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Push Servlet</servlet-name>
    <url-pattern>/__richfaces_push</url-pattern>
</servlet-mapping>

<!-- setups servlet-mapping in RichFaces configuration -->
<context-param>
    <param-name>org.richfaces.push.handlerMapping</param-name>
    <param-value>/__richfaces_push</param-value>
</context-param>

Adding action to the managed bean

Let’s open and edit RichBean.java under src/main/java in package you have defined. Add following methods:

public Date getDate() {
    return new Date();
}

public void push() throws MessageException {
    TopicKey topicKey = new TopicKey("sampleAddress");
    TopicsContext topicsContext = TopicsContext.lookup();
 
    topicsContext.publish(topicKey, "empty message");
 
    System.out.println("push event");
}

Adding component to the page

Open and edit index.xhtml file under src/main/webapp directory.

Replace contents inside of <h:form> with following snippet:

<a4j:commandButton value="Push!" action="#{richBean.push}" />

<a4j:push address="sampleAddress">
    <a4j:ajax event="dataavailable" render="outputDate" />
</a4j:push>

<a4j:outputPanel id="outputDate">
    Date: #{richBean.date}
</a4j:outputPanel>

Accessing sample

When opening http://localhost:8080/simplepush/ again, you should see one button and output with the date.

When clicking on the button, the date should be updated.
But it’s not simple AJAX!

In the background, <a4j:push> opens long-lived session to the server. When you hit button, a server action method publishes the message and RichFaces sends it to all clients which are subscribed to listen on given address topic (determined by the TopicKey). When clients receive that message, an event is fired in order to trigger an AJAX update of the date output.

An advantage over the traditional poll technique is that clients are updated without the necessity of periodically connecting to the server - it off-loads server and provides immediate client updates.

Note: I know, this sample is quite artificial, because real-world applications won’t use a4j:push and updated area on the same page, but the purpose of the blog was mainly show you configuration of the RichFaces Push.

Troubleshooting

If anything didn’t work for you, perhaps you just used the wrong environment and/or you need to configure something additionally, just look at Starting with RichFaces Push on Various Containers article.


Summary

It was necessary to only add Atmosphere libraries to the project generated from SimpleApp archetype, we have made sure that the push servlet is registered and we have setup page and bean with action simply - just enough for showcasing Push component.

Pretty simple, isn’t it?

Who knows what I will cover next time regarding the Push technology in RichFaces? :-)

Hmm, just stay tuned!

Thursday, August 18, 2011

Push Improvements in RichFaces 4.1

The lot of improvements has been done in 4.1.0.Milestone1 and specifically Push component has been tweaked a much under the hood.

Push component itself is very important for interactive enterprise applications and we are trying to design its API as much clean as possible.

RichFaces team, and Nick Belaevski namely, did great job to decouple Push from JMS to avoid unnecessary overhead with connecting to messaging provider.

On the client-side, changes have been done to support WebSockets as light-weight alternative for long-polling HTTP connections (comet). Clients, which supports them, uses WebSockets by default and fall-backs to long-polling when support is not detected.

Specifically for 4.0.0.Final users, which would like to try M1 release, they may register message stating deprecation of PushFilter in the server log. It is not strictly necessary to re-configure, but PushFilter has been replaced by PushServlet, to which it delegates now. Things are even better in Servlets 3.0 environments, when you don’t need register any servlet since that will be done automatically for you.

On the server-side, we have introduced option for disabling Push and JMS integration in cases when you can’t use enterprise messaging or you don't require it. To turn JMS integration off, you just need to provide following contextual parameter in web.xml:

<context-param>

<param-name>org.richfaces.push.jms.disable</param-name>
<param-value>true</param-value>
</context-param>


If you would like to try Push, you may be pleased that it is now in RichFaces Showcase, however be aware that it can't be seen in demo hosted on GAE since this hosting doesn't support JMS. You will need to deploy it at own, and in such case I strongly recommend you my previous blog.

And what you may expect in near future? We are working on integration with CDI Events feature, so your application would be allowed to throw messages to the clients very easily. This feature can be already seen in RichFaces Showcase Push samples - it is not really hard to develop simple integration with CDI.

But there were also issues which we had to overcome - one of them is issue with Atmosphere and JBoss Web which will be addressed also in M2.

To overcome this issue, you can temporary switch to using blocking I/O approach:

<context-param>

<param-name>org.atmosphere.useBlocking</param-name>
<param-value>true</param-value>
</context-param>


And off-course, if you have ideas how to make Push more user-friendly than it already is, give us know in RichFaces community discussions. We will be pleased to hear from you!