Using Primefaces PrimePush with Tomcat 7

Thursday October 04, 2012 ()

PrimePush comes bundled with PrimeFaces.  It uses Atmosphere,  a WebSocket/Comet framework for asynchronous server-browser communications.   Atmosphere however does not come with PrimeFaces out of the box.   You need add to your project the necessary Atmosphere runtime libraries.   In this blog  we will show you how to get going with PrimePush in PrimeFaces 3.4.1 for use with Tomcat 7 (tested with Tomcat 7.0.27).

Atmosphere EE6

Ant

For purposes of this blog we use ver 1.01 of Atmosphere EE6 and PrimeFaces 3.4.1.   Start by downloading the library here:

http://search.maven.org/#browse|-1161903243

You will need following jar files:

atmosphere-annotations-1.0.1.jar
atmosphere-compat-jbossweb-1.0.1.jar
atmosphere-compat-tomcat-1.0.1.jar
atmosphere-compat-tomcat7-1.0.1.jar
atmosphere-runtime-1.0.1.jar

This version of Atmosphere needs SLF4J for logging.   Also for purposes of this blog, we used ver 1.7.1 of SLF4J.   It can be downloaded here:

http://www.slf4j.org/download.html

You will need only the following SLF4J jars:

slf4j-api-1.7.1.jar
slf4j-simple-1.7.1.jar

Add the preceeding jar files mentioned to your project together with your PrimeFaces and other libraries required by your project.

Maven

For Maven projects add the following in the pom.xml of your project.  Don't forget to also include the entries for PrimeFaces and other libraries required by your project.

        <dependency>
            <groupId>org.atmosphere</groupId>
            <artifactId>atmosphere-runtime</artifactId>
            <version>1.0.1</version>
        </dependency> 
        
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.1</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.1</version>
        </dependency>

PrimeFaces Project

The web descriptor file (web.xml) of your project should define the PrimeFaces PushServlet.  This servlet extends org.atmosphere.cpr.AtmosphereServlet.    The entry to register PushServet should look like below.


    <servlet>
        <servlet-name>Push Servlet</servlet-name>
        <servlet-class>org.primefaces.push.PushServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <init-param>
            <param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name>
            <param-value>org.atmosphere.cache.HeaderBroadcasterCache</param-value>
        </init-param>
        <init-param>
            <param-name>org.atmosphere.cpr.broadcasterClass</param-name>
            <param-value>org.atmosphere.cpr.DefaultBroadcaster</param-value>
        </init-param>
        <init-param>
            <param-name>org.atmosphere.cpr.broadcastFilterClasses</param-name>
            <param-value>org.atmosphere.client.TrackMessageSizeFilter</param-value>
        </init-param>
        <init-param>
            <param-name>org.atmosphere.cpr.sessionSupport</param-name>
            <param-value>true</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>Push Servlet</servlet-name>
        <url-pattern>/primepush/*</url-pattern>
    </servlet-mapping>

Please note that the configuration above uses WebSocket (default). If you are using a Tomcat version earlier than 7.0.27, you may want to turn off the use of WebSocket by adding org.atmosphere.useWebSocket with a value of false.

Please consult your Atmosphere documentation for more options. You can also find more configuration options from the following page:

https://github.com/Atmosphere/atmosphere/wiki/Configuring-Atmosphere-using-the-web.xml-or-atmosphere.xml

And finally the code.  To make this demonstration simple and clear,  we use the counter sample from PrimeFaces demo site.



<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Facelet Title
    </h:head>
    <h:body>
        <h:form id="form">  
            <h:outputText id="out" value="#{pushBean.count}" 
		styleClass="ui-widget display" />  
            <br />  
            <p:commandButton value="Click" actionListener="#{pushBean.increment}" />  
        </h:form>  

        <p:socket onMessage="handleMessage" channel="/counter" />  

         <script type="text/javascript">
                function handleMessage(data) {
                    $('.display').html(data);
                }          
        </script>
    </h:body>
</html>

The <p:socket /> component makes things happen. The channel attribute of this component is the server-browser communication channel. When messages are received from the server end of the channel, the value of onMessage, a JavaScript code, is executed.

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.push.PushContext;
import org.primefaces.push.PushContextFactory;

@ManagedBean
@SessionScoped
public class PushBean implements java.io.Serializable {

    public PushBean() {
    }
    private int count;

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public synchronized void increment() {
        count++;
        PushContext pushContext = PushContextFactory.getDefault().getPushContext();
        pushContext.push("/counter", String.valueOf(count));
    }
}

Communication is initiated by the server, this is accomplished by PushContext.push(channel,data) shown above. Push broadcasts data to all waiting clients.

Tomcat 7

Atmosphere over Tomcat version 7.0.27 and later works regardless of the IO connector (BIO, NIO or APR) being used.

That's it. Good luck.


12,383

Comments (Using Primefaces PrimePush with Tomcat 7 )