Pages

Sunday, March 17, 2013

PrimePush in Jboss AS 7

It toke me a while to make PrimePush work in JBoss AS 7.
In this post I will just paste the codes of a simple hello world like program that uses PrimePush libraries to submit an String to a web socket.

The requirement for this exercise, is that you know to create a new JSF project with maven and deploy it into the JBoss 7 AS application server. All the steps to do that can be found in one of my previous post:
http://javing.blogspot.ie/2013/01/how-to-create-new-jsf-21-project-and.html

Once you have your project ready, lets make the following changes in the configuration files:

pom.xml


1:  <?xml version="1.0" encoding="UTF-8"?>  
2:  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
3:       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
4:       <modelVersion>4.0.0</modelVersion>  
5:       <groupId>my.test.project</groupId>  
6:       <artifactId>my.test.project</artifactId>  
7:       <version>0.0.1-SNAPSHOT</version>  
8:       <packaging>war</packaging>  
9:       <name>Java EE 6 webapp project</name>  
10:       <properties>  
11:            <jboss.bom.version>1.0.0.Final</jboss.bom.version>  
12:            <version.faces.mojarra>2.1.7</version.faces.mojarra>  
13:            <version.primefaces>3.4.2</version.primefaces>  
14:            <version.atmosphere>1.0.8</version.atmosphere>  
15:       </properties>  
16:       <dependencyManagement>  
17:            <dependencies>  
18:                 <dependency>  
19:                      <groupId>org.jboss.bom</groupId>  
20:                      <artifactId>jboss-javaee-6.0-with-tools</artifactId>  
21:                      <version>${jboss.bom.version}</version>  
22:                      <type>pom</type>  
23:                      <scope>import</scope>  
24:                 </dependency>  
25:                 <dependency>  
26:                      <groupId>junit</groupId>  
27:                      <artifactId>junit</artifactId>  
28:                      <version>4.10</version>  
29:                      <type>jar</type>  
30:                      <scope>test</scope>  
31:                 </dependency>  
32:            </dependencies>  
33:       </dependencyManagement>  
34:       <dependencies>  
35:            <dependency>  
36:                 <groupId>javax.enterprise</groupId>  
37:                 <artifactId>cdi-api</artifactId>  
38:                 <scope>provided</scope>  
39:            </dependency>  
40:            <dependency>  
41:                 <groupId>org.jboss.spec.javax.servlet</groupId>  
42:                 <artifactId>jboss-servlet-api_3.0_spec</artifactId>  
43:                 <scope>provided</scope>  
44:            </dependency>  
45:            <dependency>  
46:                 <groupId>org.jboss.spec.javax.faces</groupId>  
47:                 <artifactId>jboss-jsf-api_2.1_spec</artifactId>  
48:                 <scope>provided</scope>  
49:            </dependency>  
50:            <dependency>  
51:                 <groupId>org.jboss.spec.javax.el</groupId>  
52:                 <artifactId>jboss-el-api_2.2_spec</artifactId>  
53:                 <scope>provided</scope>  
54:            </dependency>  
55:            <dependency>  
56:                 <groupId>com.sun.faces</groupId>  
57:                 <artifactId>jsf-impl</artifactId>  
58:                 <version>${version.faces.mojarra}</version>  
59:                 <scope>provided</scope>  
60:            </dependency>  
61:            <dependency>  
62:                 <groupId>org.primefaces</groupId>  
63:                 <artifactId>primefaces</artifactId>  
64:                 <version>${version.primefaces}</version>  
65:            </dependency>  
66:            <dependency>  
67:                 <groupId>org.atmosphere</groupId>  
68:                 <artifactId>atmosphere-runtime</artifactId>  
69:                 <version>${version.atmosphere}</version>  
70:                 <exclusions>  
71:                      <exclusion>  
72:                           <artifactId>slf4j-api</artifactId>  
73:                           <groupId>org.slf4j</groupId>  
74:                      </exclusion>  
75:                 </exclusions>  
76:            </dependency>  
77:            <dependency>  
78:                 <groupId>junit</groupId>  
79:                 <artifactId>junit</artifactId>  
80:                 <scope>test</scope>  
81:            </dependency>  
82:       </dependencies>  
83:       <build>  
84:            <finalName>pushcomment</finalName>  
85:            <plugins>  
86:                 <plugin>  
87:                      <artifactId>maven-compiler-plugin</artifactId>  
88:                      <version>2.3.1</version>  
89:                      <configuration>  
90:                           <source>1.6</source>  
91:                           <target>1.6</target>  
92:                      </configuration>  
93:                 </plugin>  
94:                 <plugin>  
95:                      <artifactId>maven-war-plugin</artifactId>  
96:                      <version>2.1.1</version>  
97:                      <configuration>  
98:                           <failOnMissingWebXml>false</failOnMissingWebXml>  
99:                      </configuration>  
100:                 </plugin>  
101:            </plugins>  
102:       </build>  
103:       <repositories>  
104:            <repository>  
105:                 <id>prime-repo</id>  
106:                 <name>PrimeFaces Maven Repository</name>  
107:                 <url>http://repository.primefaces.org</url>  
108:                 <layout>default</layout>  
109:            </repository>  
110:       </repositories>  
111:  </project>  

faces-config.xml


1:  <?xml version="1.0" encoding="UTF-8"?>  
2:  <!-- This file is not required if you don't need any extra configuration. -->  
3:  <faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"  
4:    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
5:    xsi:schemaLocation="  
6:      http://java.sun.com/xml/ns/javaee  
7:      http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">  
8:  </faces-config>  

web.xml

1:  <?xml version="1.0" encoding="UTF-8"?>  
2:  <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
3:       xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
4:       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  
5:       version="3.0">  
6:       <display-name>push-comment</display-name>  
7:       <welcome-file-list>  
8:            <welcome-file>index.html</welcome-file>  
9:       </welcome-file-list>  
10:       <context-param>  
11:            <param-name>javax.faces.PROJECT_STAGE</param-name>  
12:            <param-value>Development</param-value>  
13:       </context-param>  
14:       <context-param>  
15:            <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>  
16:            <param-value>2</param-value>  
17:       </context-param>  
18:       <context-param>  
19:            <param-name>javax.faces.DEFAULT_SUFFIX</param-name>  
20:            <param-value>.xhtml</param-value>  
21:       </context-param>  
22:       <context-param>  
23:            <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>  
24:            <param-value>true</param-value>  
25:       </context-param>  
26:       <context-param>  
27:            <param-name>javax.faces.STATE_SAVING_METHOD</param-name>  
28:            <param-value>server</param-value>  
29:       </context-param>  
30:       <context-param>  
31:            <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>  
32:            <param-value>true</param-value>  
33:       </context-param>  
34:       <context-param>  
35:            <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>  
36:            <param-value>true</param-value>  
37:       </context-param>  
38:       <context-param>  
39:            <param-name>com.sun.faces.numberOfLogicalViews</param-name>  
40:            <param-value>5</param-value>  
41:       </context-param>  
42:       <context-param>  
43:            <param-name>com.sun.faces.numberOfViewsInSession</param-name>  
44:            <param-value>3</param-value>  
45:       </context-param>  
46:       <context-param>  
47:            <param-name>com.sun.faces.compressViewState</param-name>  
48:            <param-value>true</param-value>  
49:       </context-param>  
50:       <context-param>  
51:            <param-name>com.sun.faces.serializeServerState</param-name>  
52:            <param-value>false</param-value>  
53:       </context-param>  
54:       <context-param>  
55:            <param-name>com.sun.faces.preferXHTML</param-name>  
56:            <param-value>true</param-value>  
57:       </context-param>  
58:       <context-param>  
59:            <param-name>com.sun.faces.disableVersionTracking</param-name>  
60:            <param-value>true</param-value>  
61:       </context-param>  
62:       <context-param>  
63:            <param-name>primefaces.THEME</param-name>  
64:            <param-value>aristo</param-value>  
65:       </context-param>  
66:       <security-constraint>  
67:            <display-name>Restrict direct access to XHTML documents.</display-name>  
68:            <web-resource-collection>  
69:                 <web-resource-name>XHTML</web-resource-name>  
70:                 <url-pattern>*.xhtml</url-pattern>  
71:            </web-resource-collection>  
72:            <auth-constraint>  
73:                 <description>No roles defined for direct access to XHTML documents.</description>  
74:            </auth-constraint>  
75:       </security-constraint>  
76:       <session-config>  
77:            <session-timeout>20</session-timeout>  
78:       </session-config>  
79:       <error-page>  
80:            <exception-type>javax.faces.application.ViewExpiredException</exception-type>  
81:            <location>/index.jsf</location>  
82:       </error-page>  
83:       <servlet>  
84:            <servlet-name>Faces Servlet</servlet-name>  
85:            <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>  
86:            <load-on-startup>1</load-on-startup>  
87:            <async-supported>true</async-supported>  
88:       </servlet>  
89:       <servlet-mapping>  
90:            <servlet-name>Faces Servlet</servlet-name>  
91:            <url-pattern>/faces/*</url-pattern>  
92:       </servlet-mapping>  
93:       <servlet-mapping>  
94:            <servlet-name>Faces Servlet</servlet-name>  
95:            <url-pattern>*.jsf</url-pattern>  
96:       </servlet-mapping>  
97:       <servlet>  
98:            <servlet-name>Push Servlet</servlet-name>  
99:            <servlet-class>org.primefaces.push.PushServlet</servlet-class>  
100:            <init-param>  
101:                 <param-name>org.atmosphere.useWebSocket</param-name>  
102:                 <param-value>false</param-value>  
103:            </init-param>  
104:            <init-param>  
105:                 <param-name>org.atmosphere.cpr.sessionSupport</param-name>  
106:                 <param-value>true</param-value>  
107:            </init-param>  
108:            <init-param>  
109:                 <param-name>org.atmosphere.useNative</param-name>  
110:                 <param-value>true</param-value>  
111:            </init-param>  
112:            <init-param>  
113:                 <param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name>  
114:                 <param-value>org.atmosphere.cache.HeaderBroadcasterCache</param-value>  
115:            </init-param>  
116:            <init-param>  
117:                 <param-name>org.atmosphere.cpr.broadcastFilterClasses</param-name>  
118:                 <param-value>org.atmosphere.client.TrackMessageSizeFilter</param-value>  
119:            </init-param>  
120:            <init-param>  
121:                 <param-name>org.atmosphere.resumeOnBroadcast</param-name>  
122:                 <param-value>true</param-value>  
123:            </init-param>  
124:            <load-on-startup>1</load-on-startup>  
125:            <async-supported>true</async-supported>  
126:       </servlet>  
127:       <servlet-mapping>  
128:            <servlet-name>Push Servlet</servlet-name>  
129:            <url-pattern>/primepush/*</url-pattern>  
130:       </servlet-mapping>  
131:  </web-app>  

Now that everything should be configured, lets write a very simple JSF 2 program to show a primepush.

index.xhtml


1:  <!DOCTYPE html>  
2:  <html xmlns="http://www.w3.org/1999/xhtml"  
3:       xmlns:h="http://java.sun.com/jsf/html"  
4:       xmlns:f="http://java.sun.com/jsf/core"  
5:       xmlns:c="http://java.sun.com/jsp/jstl/core"  
6:       xmlns:ui="http://java.sun.com/jsf/facelets"  
7:       xmlns:p="http://primefaces.org/ui">  
8:  <f:view contentType="text/html" encoding="UTF-8">  
9:       <h:head>  
10:            <meta charset="utf-8" />  
11:       </h:head>  
12:       <h:body>  
13:            <h:form prependId="false">  
14:                 <p:inputTextarea id="cmt" value="#{myCommentBean.comment}"></p:inputTextarea>  
15:                 <p:commandButton actionListener="#{myCommentBean.publish}"  
16:                      process="cmt @this" update="cmt" value="publish"></p:commandButton>  
17:            </h:form>  
18:            <span id="pushComment" />  
19:            <p:socket channel="/comment" onMessage="handleMessage"></p:socket>  
20:            <script type="text/javascript">  
21:       function handleMessage(data)  
22:        {   
23:        jQuery('#pushComment').text(data);  
24:               }  
25:      </script>  
26:       </h:body>  
27:  </f:view>  
28:  </html>  

MyCommentBean.java



1:  /**  
2:   * The JSF Backing bean that will push the messages into the socket.  
3:   */  
4:  package my.first.push.project;  
5:  import javax.faces.bean.ManagedBean;  
6:  import javax.faces.bean.RequestScoped;  
7:  import org.primefaces.push.PushContextFactory;  
8:  @ManagedBean(name = "myCommentBean")  
9:  @RequestScoped  
10:  public class MyCommentBean {  
11:    public static final String BROADCAST_CHANNEL = "/comment";  
12:    private String comment;  
13:    public String getComment() {return comment;}  
14:    public void setComment(String comment) {this.comment = comment;}  
15:    public void publish() {  
16:     PushContextFactory.getDefault().getPushContext().push(BROADCAST_CHANNEL, this.comment);  
17:     this.comment = "";  
18:    }  
19:  }  

So now that we have the application, compile and deploy it in JBoss.
Run it on your browser by just accessing the URL:
http://localhost:8080/pushcomment/

Open a few browsers and see how all the clients listening to the socket will get the updates:



Download this project from:

http://www.2shared.com/file/Vy8ZSkUQ/pushcomment.html

6 comments:

  1. Do you happen to know how a node.js http client can receive a prime push event instead of a browser? Thanks.

    ReplyDelete
    Replies
    1. I got this to work using EventSource node module.

      var s = new EventSource("http://site:8080/servletName/primefacesServletName/pushChannel);

      s.addEventListener('message', function(e){
      //e.data is what you got from the server side push event
      },false);

      s.addEventListener('open', function(e) {

      }, false);

      Delete
  2. Sorry I am afraid I don't know the answer to that.
    If you use JSF maybe there is a way to hook somehow that push to an specific resource bundle, or something like that.

    ReplyDelete
  3. Thaks for this example!

    Unfortunately, the message is still received only 60 times. After that treshold, the content keeps being pushed regularly, but the page doesn't get updated anymore and needs to be refreshed.

    ReplyDelete
    Replies
    1. @lucaster Sorry, then I don't know how to help yoy. The only thing left in my mind is clustering. I never did it yet in JBoss AS 7. Time ago I did one little tutorial to implement clustering in glassfish, check this link: http://javing.blogspot.ie/2012/05/glassfish-31-clustering.html
      I also did not try prime push with glassfish but I think it works very well.

      Delete
  4. Hi Arun,
    Glad you liked the article... Advertising for free in my blog uh? ;) What do I get? hahaha....

    ReplyDelete

Share with your friends