PrimeFaces Push CHAT showcase source code

UI Components for JSF
smithh032772
Posts: 6144
Joined: 10 Sep 2011, 21:10

29 Jul 2013, 12:23

Since there has been some recent discussion about PrimeFaces Push - Chat showcase example (and source code), I decided to share mine, here, and start a different/separate/new thread about it.

NOTE:

1. this code works for me where ONLY 1 browser per device connects to server.
2. Below, I provided CDI and JSF-managed-bean versions of ChatUsers.java and ChatView.java
3. As I mentioned in other/related forum topics, the code I am sharing is for MULTIPLE devices and MULTIPLE devices ONLY!
4. The screen capture below shows that I logged into the web app via my phone, tablet, and desktop (in that order), and I entered messages, and the messages showed up on all 'devices'.

Image

chat.xhtml

Code: Select all

<?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:p="http://primefaces.org/ui">
    <h:head>
        <title>PrimePush - Chat</title>
        
        <style>
            .chatlogs {
                width: 400px;
                height: 200px;
                overflow: auto;
                padding: 0.5em 1em 0.5em 0.5em;
            }
            .messageInput {
                width: 400px;
            }            
            .usersList {
                height: 200px;
                overflow: auto;
            }
        </style>
    </h:head>
    <h:body>
        
        <p:growl id="growl" showDetail="true" />

        <h:form id="form">

            <p:remoteCommand name="updateUserList" update="users"/>
            
            <p:commandLink value="Return to PrimeFaces Push - Examples"
                           action="index" ajax="false" immediate="true"/>
            <p:fieldset id="container" legend="PrimeChat" toggleable="true">

                <h:panelGroup rendered="#{chatView.loggedIn}">

                    <h:panelGrid columns="2" columnClasses="publicColumn,usersColumn" style="width:100%">
                        <p:outputPanel id="public" layout="block" styleClass="ui-corner-all ui-widget-content chatlogs"/>

                        <p:dataList id="users" var="user" value="#{chatUsers.users}" styleClass="usersList">
                            <f:facet name="header">
                                Users
                            </f:facet>

                            <p:commandButton title="Chat" icon="ui-icon-comment" oncomplete="pChat.show()" update=":form:privateChatContainer">
                                <f:setPropertyActionListener value="#{user}" target="#{chatView.privateUser}" />
                            </p:commandButton>
                            #{user}
                        </p:dataList>
                    </h:panelGrid>

                    <p:separator />

                    <p:inputText value="#{chatView.globalMessage}" styleClass="messageInput" />
                    <p:spacer width="5" />
                    <p:commandButton value="Send" actionListener="#{chatView.sendGlobal}" oncomplete="$('.messageInput').val('').focus()"/>
                    <p:spacer width="5" />
                    <p:commandButton value="Disconnect" actionListener="#{chatView.disconnect}" global="false" update="container" />
                </h:panelGroup>

                <h:panelGroup rendered="#{not chatView.loggedIn}" >
                    Username: <p:inputText value="#{chatView.username}" />

                    <p:spacer width="5" />
                    <p:commandButton value="Login" actionListener="#{chatView.login}" update="container" 
                                        icon="ui-icon-person" />
                </h:panelGroup>

            </p:fieldset>

            <p:dialog widgetVar="pChat" header="Private Chat" modal="true" showEffect="fade" hideEffect="fade">
                <h:panelGrid id="privateChatContainer" columns="2" columnClasses="vtop,vtop">
                    <p:outputLabel for="pChatInput" value="To: #{chatView.privateUser}" />
                    <p:inputTextarea id="pChatInput" value="#{chatView.privateMessage}" rows="5" cols="30" />

                    <p:spacer />
                    <p:commandButton value="Send" actionListener="#{chatView.sendPrivate}" oncomplete="pChat.hide()" />
                </h:panelGrid>
            </p:dialog>

        </h:form>

        <p:socket onMessage="handleMessage" channel="/chat" autoConnect="false" widgetVar="subscriber"/>

        <script type="text/javascript">
            function handleMessage(data) {
                if (data.indexOf("updateUserList()") !== -1) {
                    updateUserList();
                }
                else {
                    var chatContent = $(PrimeFaces.escapeClientId('form:public'));
                    chatContent.append(data + '<br />');

                    //keep scroll
                    chatContent.scrollTop(chatContent.height());
                }
            }
        </script>
                    
    </h:body>
</html>
CDI ChatUsers.java

Code: Select all

/*
 * Copyright 2009-2012 Prime Teknoloji.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.primepush;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;

@Named
@ApplicationScoped
public class ChatUsers implements Serializable {
    
    private List<String> users;
    
    public ChatUsers() {
        
    }
    
    @PostConstruct
    public void init() {
        this.users = new ArrayList<String>();
    }

    public List<String> getUsers() {
        return users;
    }

    public void setUsers(List<String> users) {
        this.users = users;
    }
    
    public void addUser(String user) {
        this.users.add(user);
    }
    
    public void removeUser(String user) {
        this.users.remove(user);
    }
    
    public boolean contains(String user) {
        return this.users.contains(user);
    }
}
CDI ChatView.java

Code: Select all

package com.primepush;

import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import org.primefaces.context.RequestContext;
import org.primefaces.push.PushContext;
import org.primefaces.push.PushContextFactory;

@Named
@SessionScoped
public class ChatView implements Serializable {
    
    private PushContext pushContext = PushContextFactory.getDefault().getPushContext();
    
    @Inject
    private ChatUsers users;

    private String privateMessage;
    
    private String globalMessage;
	
    private String username;

    private boolean loggedIn;
    
    private String privateUser;
    
    private final static String CHANNEL = "/chat/";

    public ChatView() {
    }
    
    public void setUsers(ChatUsers users) {
        this.users = users;
    }

    public String getPrivateUser() {
        return privateUser;
    }

    public void setPrivateUser(String privateUser) {
        this.privateUser = privateUser;
    }

    public String getGlobalMessage() {
        return globalMessage;
    }

    public void setGlobalMessage(String globalMessage) {
        this.globalMessage = globalMessage;
    }

    public String getPrivateMessage() {
        return privateMessage;
    }

    public void setPrivateMessage(String privateMessage) {
        this.privateMessage = privateMessage;
    }
    
    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }

    public boolean isLoggedIn() {
        return loggedIn;
    }
    
    public void setLoggedIn(boolean loggedIn) {
        this.loggedIn = loggedIn;
    }

    public void sendGlobal() {
        pushContext.push(CHANNEL + "*", username + ": " + globalMessage);

        globalMessage = null;
    }
    
    public void sendPrivate() {
        pushContext.push(CHANNEL + privateUser, "[PM] " + username + ": " + privateMessage);
        
        privateMessage = null;
    }
	
    public void login() {
        RequestContext requestContext = RequestContext.getCurrentInstance();

        if(users.contains(username)) {
            loggedIn = false;
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Username taken", "Try with another username."));

            requestContext.update("growl");
        }
        else {
            users.addUser(username);
            pushContext.push(CHANNEL + "*", username + " joined the channel.");
            pushContext.push(CHANNEL + "*", "updateUserList()");
            requestContext.execute("subscriber.connect('/" + username + "')");
            loggedIn = true;
        }
    }
    
    public void disconnect() {
        RequestContext requestContext = RequestContext.getCurrentInstance();

        //remove user and update ui
        users.removeUser(username);
        requestContext.update("form:users");
        requestContext.execute("subscriber.disconnect()");
        
        //push leave information
        pushContext.push(CHANNEL + "*", "updateUserList()");
        pushContext.push(CHANNEL + "*", username + " left the channel.");
        
        //reset state
        loggedIn = false;
        username = null;
    }
}
JSF ChatUsers.java

Code: Select all

/*
 * Copyright 2009-2012 Prime Teknoloji.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.primepush;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;

@ManagedBean
@ApplicationScoped
public class ChatUsers implements Serializable {
    
    private List<String> users;
    
    public ChatUsers() {
        
    }
    
    @PostConstruct
    public void init() {
        this.users = new ArrayList<String>();
    }

    public List<String> getUsers() {
        return users;
    }

    public void setUsers(List<String> users) {
        this.users = users;
    }
    
    public void addUser(String user) {
        this.users.add(user);
    }
    
    public void removeUser(String user) {
        this.users.remove(user);
    }
    
    public boolean contains(String user) {
        return this.users.contains(user);
    }
}
JSF ChatView.java

Code: Select all

package com.primepush;

import java.io.Serializable;
import javax.faces.application.FacesMessage;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.FacesContext;
import org.primefaces.context.RequestContext;
import org.primefaces.push.PushContext;
import org.primefaces.push.PushContextFactory;

@ManagedBean
@SessionScoped
public class ChatView implements Serializable {
    
    private PushContext pushContext = PushContextFactory.getDefault().getPushContext();
    
    /*
     * Injecting managed beans in each other
     * http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html#InjectingManagedBeansInEachOther
     */
    @ManagedProperty("#{chatUsers}")
    private ChatUsers users;

    private String privateMessage;
    
    private String globalMessage;
	
    private String username;

    private boolean loggedIn;
    
    private String privateUser;
    
    private final static String CHANNEL = "/chat/";

    public ChatView() {
    }
    
    /*
     * Injecting managed beans in each other
     * http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html#InjectingManagedBeansInEachOther
     */
    public void setUsers(ChatUsers users) {
        this.users = users;
    }

    public String getPrivateUser() {
        return privateUser;
    }

    public void setPrivateUser(String privateUser) {
        this.privateUser = privateUser;
    }

    public String getGlobalMessage() {
        return globalMessage;
    }

    public void setGlobalMessage(String globalMessage) {
        this.globalMessage = globalMessage;
    }

    public String getPrivateMessage() {
        return privateMessage;
    }

    public void setPrivateMessage(String privateMessage) {
        this.privateMessage = privateMessage;
    }
    
    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }

    public boolean isLoggedIn() {
        return loggedIn;
    }
    
    public void setLoggedIn(boolean loggedIn) {
        this.loggedIn = loggedIn;
    }

    public void sendGlobal() {
        pushContext.push(CHANNEL + "*", username + ": " + globalMessage);

        globalMessage = null;
    }
    
    public void sendPrivate() {
        pushContext.push(CHANNEL + privateUser, "[PM] " + username + ": " + privateMessage);
        
        privateMessage = null;
    }
	
    public void login() {
        RequestContext requestContext = RequestContext.getCurrentInstance();

        if(users.contains(username)) {
            loggedIn = false;
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Username taken", "Try with another username."));

            requestContext.update("growl");
        }
        else {
            users.addUser(username);
            pushContext.push(CHANNEL + "*", username + " joined the channel.");
            pushContext.push(CHANNEL + "*", "updateUserList()");
            requestContext.execute("subscriber.connect('/" + username + "')");
            loggedIn = true;
        }
    }
    
    public void disconnect() {
        RequestContext requestContext = RequestContext.getCurrentInstance();

        //remove user and update ui
        users.removeUser(username);
        requestContext.update("form:users");
        requestContext.execute("subscriber.disconnect()");
        
        //push leave information
        pushContext.push(CHANNEL + "*", "updateUserList()");
        pushContext.push(CHANNEL + "*", username + " left the channel.");
        
        //reset state
        loggedIn = false;
        username = null;
    }
}
web.xml (see my signature for my test/development environment details; this works with tomee, myfaces, openwebbeans, but this might not work with glassfish, mojarra, etc...)

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 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-app_3_0.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Production</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>server</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.EL_RESOLVER_COMPARATOR</param-name>
        <param-value>org.apache.myfaces.el.unified.OpenWebBeansELResolverComparator</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.CACHE_EL_EXPRESSIONS</param-name>
        <param-value>always</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.COMPRESS_STATE_IN_SESSION</param-name>
        <param-value>false</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name>
        <param-value>10</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
        <param-value>false</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
        <param-value>-1</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.CHECK_ID_PRODUCTION_MODE</param-name>
        <param-value>false</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.VIEW_UNIQUE_IDS_CACHE_ENABLED</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.SAVE_STATE_WITH_VISIT_TREE_ON_PSS</param-name>
        <param-value>false</param-value>
    </context-param>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <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>false</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>Push Servlet</servlet-name>
        <url-pattern>/primepush/*</url-pattern>
    </servlet-mapping>
    
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>
Please feel free to share your code and/or test results, and discuss further.
Last edited by smithh032772 on 16 Aug 2013, 15:10, edited 4 times in total.
Howard

PrimeFaces 6.0, Extensions 6.0.0, Push (Atmosphere 2.4.0)
TomEE+ 1.7.4 (Tomcat 7.0.68), MyFaces Core 2.2.9, JDK8
JUEL 2.2.7 | OmniFaces | EclipseLink-JPA/Derby | Chrome

Java EE 6 Tutorial|NetBeans|Google|Stackoverflow|PrimeFaces|Apache

bhanu
Posts: 54
Joined: 25 Jun 2013, 16:15

29 Jul 2013, 13:05

when run this code i got null pointer exception at

Code: Select all

  if(users.contains(username)) {
tomcat 7.0.38
prime faces version 3.5
mojarra 2.1.6

smithh032772
Posts: 6144
Joined: 10 Sep 2011, 21:10

29 Jul 2013, 13:40

look at my signature and how much details I share in my responses. you need to share more details in your responses. your response (null pointer exception) is not enough detail at all.

I am using OpenWebBeans for my CDI code. from your previous posts, I think you are just using tomcat.

click your username in upper right corner of this page, click Profile, click Signature, and add your test/development environment details in your signature... so we know your web app container and version (tomcat 7.0.42), primefaces version (primefaces 3.5), and JSF implementation (Mojarra 2.1.x, 2.2.x, or MyFaces 2.1.x), and if you are using OpenWebBeans for CDI code, then include OpenWebBeans version. If you are using PrimeFaces Push, then state the Atmosphere version that you are using (atmosphere 2.0.0.RC1).
Howard

PrimeFaces 6.0, Extensions 6.0.0, Push (Atmosphere 2.4.0)
TomEE+ 1.7.4 (Tomcat 7.0.68), MyFaces Core 2.2.9, JDK8
JUEL 2.2.7 | OmniFaces | EclipseLink-JPA/Derby | Chrome

Java EE 6 Tutorial|NetBeans|Google|Stackoverflow|PrimeFaces|Apache

bhanu
Posts: 54
Joined: 25 Jun 2013, 16:15

29 Jul 2013, 14:11

the error at bean class

Code: Select all

package com.nitspl;

import java.io.Serializable;
import javax.faces.application.FacesMessage;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import org.primefaces.context.RequestContext;
import org.primefaces.push.PushContext;
import org.primefaces.push.PushContextFactory;

@SuppressWarnings("serial")
@SessionScoped
public class NewChatView implements Serializable {
    
    private PushContext pushContext = PushContextFactory.getDefault().getPushContext();
    
   
    private ChatUsers users;

    private String privateMessage;
    
    private String globalMessage;
   
    private String username="bhanu";

    private boolean loggedIn;
    
    private String privateUser;
    
    private final static String CHANNEL = "/chat/";

    public NewChatView() {
    }
    
    public void setUsers(ChatUsers users) {
        this.users = users;
    }

    public String getPrivateUser() {
        return privateUser;
    }

    public void setPrivateUser(String privateUser) {
        this.privateUser = privateUser;
    }

    public String getGlobalMessage() {
        return globalMessage;
    }

    public void setGlobalMessage(String globalMessage) {
        this.globalMessage = globalMessage;
    }

    public String getPrivateMessage() {
        return privateMessage;
    }

    public void setPrivateMessage(String privateMessage) {
        this.privateMessage = privateMessage;
    }
    
    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }

    public boolean isLoggedIn() {
        return loggedIn;
    }
    
    public void setLoggedIn(boolean loggedIn) {
        this.loggedIn = loggedIn;
    }

    public void sendGlobal() {
        pushContext.push(CHANNEL + "*", username + ": " + globalMessage);

        globalMessage = null;
    }
    
    public void sendPrivate() {
        pushContext.push(CHANNEL + privateUser, "[PM] " + username + ": " + privateMessage);
        
        privateMessage = null;
    }
   
    public void login() {
        RequestContext requestContext = RequestContext.getCurrentInstance();

      if(users.contains(username)){
            loggedIn = false;
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Username taken", "Try with another username."));

            requestContext.update("growl");
        }
        else {
            users.addUser(username);
            pushContext.push(CHANNEL, username + " joined the channel.");
            requestContext.execute("subscriber.connect('/" + username + "')");
            loggedIn = true;
        }
    }
    
    public void disconnect() {
        //remove user and update ui
        users.removeUser(username);
        RequestContext.getCurrentInstance().update("form:users");
        
        //push leave information
        pushContext.push(CHANNEL, username + " left the channel.");
        
        //reset state
        loggedIn = false;
        username = null;
    }
}[/code



[code]if(users.contains(username))
at that line getting null pointer exception when login button click.
tomcat 7.0.38
prime faces version 3.5
mojarra 2.1.6

smithh032772
Posts: 6144
Joined: 10 Sep 2011, 21:10

29 Jul 2013, 14:41

you need to migrate my CDI beans to JSF-managed beans.
Howard

PrimeFaces 6.0, Extensions 6.0.0, Push (Atmosphere 2.4.0)
TomEE+ 1.7.4 (Tomcat 7.0.68), MyFaces Core 2.2.9, JDK8
JUEL 2.2.7 | OmniFaces | EclipseLink-JPA/Derby | Chrome

Java EE 6 Tutorial|NetBeans|Google|Stackoverflow|PrimeFaces|Apache

bhanu
Posts: 54
Joined: 25 Jun 2013, 16:15

29 Jul 2013, 14:49

can i know what is CDI beans??
tomcat 7.0.38
prime faces version 3.5
mojarra 2.1.6

smithh032772
Posts: 6144
Joined: 10 Sep 2011, 21:10

29 Jul 2013, 14:57

what is cdi java ee

it may be time to introduce you to tomee (tomcat + java ee). search google for 'tomee snapshot download', and download latest tomee 1.6.0 snapshot, and migrate your app to tomee, and subscribe to tomee user list. also, search google for tomee examples, as they have JSF and CDI examples, there, too.

FYI, i will edit my original post and add web.xml.
Howard

PrimeFaces 6.0, Extensions 6.0.0, Push (Atmosphere 2.4.0)
TomEE+ 1.7.4 (Tomcat 7.0.68), MyFaces Core 2.2.9, JDK8
JUEL 2.2.7 | OmniFaces | EclipseLink-JPA/Derby | Chrome

Java EE 6 Tutorial|NetBeans|Google|Stackoverflow|PrimeFaces|Apache

bhanu
Posts: 54
Joined: 25 Jun 2013, 16:15

30 Jul 2013, 09:28

in web.xml getting an exception at

Code: Select all

<servlet-name>Push Servlet</servlet-name>
        <servlet-class>org.primefaces.push.PushServlet</servlet-class>
      <load-on-startup>1</load-on-startup>  
        <init-param>

exception shows at <init-param>..
tomcat 7.0.38
prime faces version 3.5
mojarra 2.1.6

bhanu
Posts: 54
Joined: 25 Jun 2013, 16:15

30 Jul 2013, 10:18

my source code is

Chat.xhtml

Code: Select all

<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsp/jsf/core"
	xmlns:p="http://primefaces.org/ui"
	xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
	<title>Insert title here</title>

	<style type="text/css">
.chatlogs {
	height: 210px !important;
	max-height: 210px !important;
	width: 1000px !important;
	overflow-y: scroll !important;
	overflow-x: hidden !important;
}
</style>  
	
</h:head>
<h:body>

	<p:growl id="growl" showDetail="true" />

	<h:form id="form">

		<p:fieldset id="container" legend="PrimeChat" toggleable="true">

			<h:panelGroup rendered="#{chatView1.loggedIn}">

				<h:panelGrid columns="2" columnClasses="publicColumn,usersColumn"
					style="width:100%">
					<p:outputPanel id="public" layout="block"
						styleClass="ui-corner-all ui-widget-content chatlogs" />

					<p:panel id="resize" header="USERS">
						<p:resizable for="resize" />

						<p:dataList id="users" var="user" value="#{chatView1.users}"
							styleClass="usersList">

							<p:commandButton title="Chat" icon="ui-icon-comment"
								oncomplete="pChat.show()" update=":form:privateChatContainer">
								<f:setPropertyActionListener value="#{user}"
									target="#{chatView1.privateUser}" />
							</p:commandButton> 
                   
                    #{user} 
                  
              </p:dataList>
					</p:panel>
				</h:panelGrid>

				<p:separator />

				<p:inputText value="#{chatView1.globalMessage}"
					styleClass="messageInput" />
				<p:spacer width="5" />
				<p:commandButton value="Send"
					actionListener="#{chatView1.sendGlobal}"
					oncomplete="$('.messageInput').val('').focus()" />
				<p:spacer width="5" />
				<p:commandButton value="Disconnect"
					actionListener="#{chatView1.disconnect}" global="false"
					update="container" />
			</h:panelGroup>

			<h:panelGroup rendered="#{not chatView1.loggedIn}">  
            Username: <p:inputText value="#{chatView1.username}" />

				<p:spacer width="5" />
				<p:commandButton value="Login" actionListener="#{chatView1.login}"
					update="container" icon="ui-icon-person" />
			</h:panelGroup>

		</p:fieldset>

		<p:dialog widgetVar="pChat" header="Private Chat" modal="true"
			showEffect="fade" hideEffect="fade">
			<h:panelGrid id="privateChatContainer" columns="2"
				columnClasses="vtop,vtop">
				<p:outputLabel for="pChatInput" value="To: #{chatView1.privateUser}" />
				<p:inputTextarea id="pChatInput" value="#{chatView1.privateMessage}"
					rows="5" cols="30" />

				<p:spacer />

				<p:commandButton value="Send"
					actionListener="#{chatView1.sendPrivate}" oncomplete="pChat.hide()" />
			</h:panelGrid>
		</p:dialog>

	</h:form>

	<p:socket onMessage="handleMessage" channel="/chat" autoConnect="false"
		widgetVar="subscriber" />

	<script type="text/javascript">
		function handleMessage(data) {
			var chatContent = $(PrimeFaces.escapeClientId('form:public'));
			chatContent.append(data + '<br />');

			//keep scroll  
			chatContent.scrollTop(chatContent.height());
		}
	</script>


</h:body>
</html>



ChatView.java



Code: Select all

package com.nitspl;

import java.io.Serializable;
import java.util.ArrayList;

import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import org.primefaces.context.RequestContext;
import org.primefaces.push.*;

@SuppressWarnings("serial")
public class ChatView implements Serializable {
	
	private final PushContext pushContext = PushContextFactory.getDefault().getPushContext();  
    
    private List<String> users;  
	
    private String privateMessage;  
      
    private String globalMessage;  
      
    private String username;  
      
    private boolean loggedIn;  
      
    private String privateUser;  
      
    private final static String CHANNEL = "/chat/";  
  
   
   public ChatView(){

     
           users = new ArrayList<String>();  
      
    }
    
	public List<String> getUsers() {
	return users;
}

public void setUsers(List<String> users) {
	this.users = users;
}

public PushContext getPushContext() {
	return pushContext;
}


public static String getChannel() {
	return CHANNEL;
}


	public String getPrivateUser() {  
        return privateUser;  
    }  
  

	public void setPrivateUser(String privateUser) {  
        this.privateUser = privateUser;  
    }  
  
    public String getGlobalMessage() {  
        return globalMessage;  
    }  
  
    public void setGlobalMessage(String globalMessage) {  
        this.globalMessage = globalMessage;  
    }  
  
    public String getPrivateMessage() {  
        return privateMessage;  
    }  
  
    public void setPrivateMessage(String privateMessage) {  
        this.privateMessage = privateMessage;  
    }  
      
    public String getUsername() {  
        return username;  
    }  
    public void setUsername(String username) {  
        this.username = username;  
    }  
      
    public boolean isLoggedIn() {  
        return loggedIn;  
    }  
    public void setLoggedIn(boolean loggedIn) {  
        this.loggedIn = loggedIn;  
    }  
  
    
    
    
   public void sendGlobal() {  
        pushContext.push(CHANNEL + "*", username + ": " + globalMessage);  
          
        globalMessage = null;  
    }  
      
    public void sendPrivate() {  
       // pushContext.push(CHANNEL + privateUser, "[PM] " + username + ": " + privateMessage);  
    	pushContext.push(CHANNEL +"*", "[PM] " + username + ": " + privateMessage);
        privateMessage = null;  
    }  
      
    public void login() {  
        RequestContext requestContext = RequestContext.getCurrentInstance(); 
        users = new ArrayList<String>(); 
          
        if(users.contains(username)) {  
            loggedIn = false;  
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Username taken", "Try with another username."));  
              
            requestContext.update("growl");  
        }  
        else {  
            users.add(username);  
            pushContext.push(CHANNEL, username + " joined the channel." ); 
            requestContext.execute("subscriber.connect('/" + username + "')"); 
            loggedIn = true;  
          //pushContext.push("User2/CHANNEL", new FacesMessage("friendship request", "from User1"));
        }  
    }  
      
    public void disconnect() {  
        //remove user and update ui  
        users.remove(username);  
        RequestContext.getCurrentInstance().update("form:users");  
          
        //push leave information  
        pushContext.push(CHANNEL, username + " left the channel.");  
          
        //reset state  
        loggedIn = false;  
        username = null;  
    }  

}


web.xml


Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 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-app_3_0.xsd">  <display-name>PushChat1</display-name>
  <welcome-file-list>
    <welcome-file>Chat.xhtml</welcome-file>
   
  </welcome-file-list>
  
   <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>
  
  
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>
   <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>
   <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
  </servlet-mapping>
   <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsp</url-pattern>
  </servlet-mapping>
  <context-param>
    <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
  </context-param>
  <context-param>
    <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
    <param-value>resources.application</param-value>
  </context-param>
  <listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
  </listener>
</web-app>


facesconfig.xml

Code: Select all

<?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_2_1.xsd"
    version="2.1">
	<managed-bean>
		<managed-bean-name>chatView1</managed-bean-name>
		<managed-bean-class>com.nitspl.ChatView</managed-bean-class>
		<managed-bean-scope>session</managed-bean-scope>
	</managed-bean>

</faces-config>

jars i added are


atmosphere-compat-jbossweb-1.0.8.jar
atmosphere-compat-tomcat-1.0.8.jar
atmosphere-compat-tomcat7-1.0.8.jar
atmosphere-runtime-1.0.8.jar





users list canot be updated please rectify my problem...
tomcat 7.0.38
prime faces version 3.5
mojarra 2.1.6

smithh032772
Posts: 6144
Joined: 10 Sep 2011, 21:10

30 Jul 2013, 10:46

bhanu wrote:users list canot be updated please rectify my problem...
I think the cause of the problem is the following:

you defined 'users' on the bean

Code: Select all

public class ChatView implements Serializable {
	
    private List<String> users;  
bean constructor initialized 'users' on the bean

Code: Select all

   public ChatView(){

     
           users = new ArrayList<String>();  
      
    }
also, everytime user clicks Login button, bean login() initializes 'users' list; this 'should be' the cause of your problem; login button should NOT initialize 'users' list; bean 'constructor' (above) should ONLY initialize 'users' list

Code: Select all

    public void login() {  
        RequestContext requestContext = RequestContext.getCurrentInstance(); 
        users = new ArrayList<String>(); 
also, I recommend you change from client to server; GIFY (Google Is Your Friend), you can search google for 'balusc state_saving_method server client' and read about that (but that is not important here at all) :)

Code: Select all

  <context-param>
    <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>server</param-value>
  </context-param>
I do NOT recommend atmosphere 1.0.8 at all! I recommend Atmosphere 2.0.0.RC1. (click URL, and READ that forum topic, download, and replace Atmosphere 1.0.8 with 2.0.0.RC1, and REPLY here and let me know that you ONLY have 2.0.0.RC1 atmosphere-runtime JAR)

Code: Select all

atmosphere-compat-jbossweb-1.0.8.jar
atmosphere-compat-tomcat-1.0.8.jar
atmosphere-compat-tomcat7-1.0.8.jar
atmosphere-runtime-1.0.8.jar
also, you can add following load-on-startup and async-supported to push servlet in web.xml

Code: Select all

    <servlet>
        <servlet-name>Push Servlet</servlet-name>
        <servlet-class>org.primefaces.push.PushServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
I recommend that you download latest tomcat, which is 7.0.42 (today), and optional, you can/may want to download latest mojarra 2.1.x (I think it is 2.1.24, today)

Code: Select all

tomcat 7.0.38
prime faces version 3.5
mojarra 2.1.6
reply to EVERYTHING I wrote above AFTER you do everything I advised above.
Howard

PrimeFaces 6.0, Extensions 6.0.0, Push (Atmosphere 2.4.0)
TomEE+ 1.7.4 (Tomcat 7.0.68), MyFaces Core 2.2.9, JDK8
JUEL 2.2.7 | OmniFaces | EclipseLink-JPA/Derby | Chrome

Java EE 6 Tutorial|NetBeans|Google|Stackoverflow|PrimeFaces|Apache

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 27 guests