I'm trying to update a datatable after a row is added using primepush. Meaning, I want user1 to update the datatable and user2 should see the added row without refreshing the page.
My Primefaces version is 5.2 and Atmosphere runtime version is 2.3.3
Here's my relevant code which I tried to implement based on Primefaces Showcase and the User Guide:
web.xml:
<web-app 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"
version="3.0">
<display-name>PrimeFaces Web Application</display-name>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<filter>
<filter-name>AccessFilter</filter-name>
<filter-class>view.AccessFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AccessFilter</filter-name>
<url-pattern>/secured/*</url-pattern>
</filter-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>
<servlet-name>Push Servlet</servlet-name>
<servlet-class>org.primefaces.push.PushServlet</servlet-class>
<async-supported>true</async-supported>
</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>*.faces</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Push Servlet</servlet-name>
<url-pattern>/primepush/*</url-pattern>
</servlet-mapping>
</web-app>
Backing Bean:
@ManagedBean
@ViewScoped
@PushEndpoint("/main")
public class MainBean implements Serializable{
...
public void addContact(ActionEvent event){
... // database operations
Contact con = new Contact();
contacts.add(con); // this is an ArrayList
EventBus eventBus = EventBusFactory.getDefault().eventBus();
eventBus.publish("/main", contacts);
}
@OnMessage(encoders = {JSONEncoder.class})
public ArrayList<Contact> getContacts(){
return contacts;
}
}
main.xhtml:
...
<p:commandButton value="Add Contact" update=":form:datatable"
actionListener="#{mainBean.addContact}" ajax="true"/>
<h:form id="form">
<p:dataTable id="datatable" var="contact" value="#{mainBean.contacts}"
selectionMode="single" rowKey="#{contact.firstName}"
selection="#{mainBean.selectedContact}">
<p:column headerText="First Name">
<h:outputText value="#{contact.firstName}"/>
</p:column>
<p:column headerText="Last Name">
<h:outputText value="#{contact.lastName}"/>
</p:column>
</p:dataTable>
</h:form>
<p:socket channel="/main">
<p:ajax event="message" update=":form:datatable"/>
</p:socket>
When I try to add a row to the table, no errors occur but some rows just get lost. When I refresh, the table reloads as the way it should. The added row is also not passed between different users. User2 still needs to refresh to see the changes after user1 adds a value to the table.
I've also tried the suggestions in this link with no success. I'm pretty new to primepush and the examples I found online (other than the User Guide) are for really old versions of Primefaces and push feature seems to changed a lot after Primefaces 5. Any help is appreciated.
Edit: I've also tried these links: link, link, link.
Edit 2: I've logged if the push is working and it seems that it is indeed. When I navigate to the page which has push enabled, I can observe on the console that it gets activated. However, when I try to update the table, the get method of the list which is filling the table is called three times consecutively after pushing...