PushEndPoint resource class once in a while is empty

UI Components for JSF
pslzr
Posts: 11
Joined: 12 Jun 2012, 17:21

04 Aug 2014, 22:18

Push messaging is working perfectly!!.

But, once in a while, some client does not get any message.

After debugging some time I have found that when the client does not receive messages the onOpen in PushEndPoint resource class is called with <this> referencing to a same empty class!!, in such case PathParam is not initialized, apart from that, call stack in onOpen and execution appears exactly the same when it works and when it does not work.

To figure it out I set some code and log it, showed later.

I will appreciate any help.

Primefaces 5.0 (Public version)
Glassfish 4.0
Atmosphere-runtime 2.1.6 (also proved with 2.1.3)

The empty class which reference "this" once in a while (break in onOpen):

this PushResource (id=421)
sessionId null

PushResource.java content:
I have proved with singleton and without.

Code: Select all

package wda.utils;

import org.primefaces.push.EventBus;
import org.primefaces.push.RemoteEndpoint;
import org.primefaces.push.annotation.OnClose;
import org.primefaces.push.annotation.OnMessage;
import org.primefaces.push.annotation.OnOpen;
import org.primefaces.push.annotation.PathParam;
import org.primefaces.push.annotation.PushEndpoint;
import org.primefaces.push.annotation.Singleton;
import org.primefaces.push.impl.JSONEncoder;

@PushEndpoint("/events/{sessionId}/")
@Singleton

public class PushResource {
    @PathParam("sessionId")
    private String sessionId;   
	
    @OnMessage(encoders = {JSONEncoder.class})
    public Object onMessage(Object pushData) {
    	return pushData;
    }
    
    @OnOpen
    public void onOpen(RemoteEndpoint r, EventBus eventBus) {
    	if (sessionId == null)
    		System.out.println("<ERROR> Push connection not recognized, sessionId got <null>");
    	else
    		System.out.println("Push connection opened with sessionId " + sessionId);
    	
    }
    
    @OnClose
    public void onClose(RemoteEndpoint r, EventBus eventBus) {
    	if (sessionId == null)
    		System.out.println("Push connection with null sessionId closed");
    	else
    		System.out.println("Push connection closed with sessionId " + sessionId);
    }    
}
The log generated in Glassfish 4.0 console:
(Repeatedly open url from browser and close the browser) Using sometimes IE and others Chrome, no pattern regarding browser detected.

2014-08-04T11:15:08.674-0500|INFO: Push connection opened with sessionId 1cce1957482b86e33af34a97481c
2014-08-04T11:15:16.849-0500|INFO: Push connection closed with sessionId 1cce1957482b86e33af34a97481c
2014-08-04T11:15:29.134-0500|INFO: Tipo de Browser = Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0) Lenguage = 0
2014-08-04T11:15:30.241-0500|INFO: Push connection opened with sessionId 1cdd21ebb274aa207f7fe01f5225
2014-08-04T11:15:37.850-0500|INFO: Push connection closed with sessionId 1cdd21ebb274aa207f7fe01f5225
2014-08-04T11:16:15.689-0500|INFO: Push connection opened with sessionId 1cdd21ebb274aa207f7fe01f5225
2014-08-04T11:16:22.705-0500|INFO: Push connection closed with sessionId 1cdd21ebb274aa207f7fe01f5225
2014-08-04T11:16:29.039-0500|INFO: Tipo de Browser = Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36 Lenguage = 0
2014-08-04T11:16:30.257-0500|INFO: <ERROR> Push connection not recognized, sessionId got <null>
2014-08-04T11:16:38.545-0500|INFO: Push connection with null sessionId closed
2014-08-04T11:17:24.803-0500|INFO: <ERROR> Push connection not recognized, sessionId got <null>
2014-08-04T11:17:33.008-0500|INFO: Push connection with null sessionId closed


2014-08-04T12:35:48.077-0500|INFO: Push connection closed with sessionId 2172508b3c103afd64ad9aa8c8c1
2014-08-04T12:35:51.423-0500|INFO: Push connection opened with sessionId 2172508b3c103afd64ad9aa8c8c1
2014-08-04T12:35:55.295-0500|INFO: Push connection closed with sessionId 2172508b3c103afd64ad9aa8c8c1
2014-08-04T12:36:25.959-0500|INFO: Push connection opened with sessionId 2172508b3c103afd64ad9aa8c8c1
2014-08-04T12:36:31.223-0500|INFO: Push connection closed with sessionId 2172508b3c103afd64ad9aa8c8c1
2014-08-04T12:36:44.543-0500|INFO: Push connection opened with sessionId 2172508b3c103afd64ad9aa8c8c1
2014-08-04T12:36:47.842-0500|INFO: Push connection closed with sessionId 2172508b3c103afd64ad9aa8c8c1
2014-08-04T12:36:59.619-0500|INFO: Tipo de Browser = Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36 Lenguage = 0
2014-08-04T12:37:07.055-0500|INFO: <ERROR> Push connection not recognized, sessionId got <null>
2014-08-04T12:37:12.391-0500|INFO: Push connection with null sessionId closed


web.xml
atmosphere params was set and clear, no difference in behaviour.

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="Test App_ID" version="3.1">
  <display-name> etc etc </display-name>
  <description>
        Program ....
  </description>
  <context-param>
    <param-name>primefaces.THEME</param-name>
    <param-value>cupertino</param-value>
  </context-param>
  <!-- <context-param>
    <param-name>primefaces.THEME</param-name>
    <param-value>dev</param-value>
  </context-param> -->
  <context-param>
    <param-name>primefaces.CACHE_PROVIDER</param-name>
    <param-value>org.primefaces.cache.EHCacheProvider</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.PROJECT_STAGE</param-name>
    <param-value>Production</param-value>
  </context-param>
  <context-param>
    <param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
    <param-value>false</param-value>
  </context-param>
  <context-param>
    <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
    <param-value>true</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>
    <async-supported>true</async-supported>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.icap</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>Push Servlet</servlet-name>
    <servlet-class>org.primefaces.push.PushServlet</servlet-class>
	   <init-param>
	            <param-name>org.atmosphere.annotation.packages</param-name>
	            <param-value>org.primefaces.push</param-value>
	   </init-param>
	   <init-param>
	            <param-name>org.atmosphere.cpr.packages</param-name>
	            <param-value>wda.utils</param-value>
	   </init-param>
    <load-on-startup>1</load-on-startup>
    <async-supported>true</async-supported>    
  </servlet>
  <servlet-mapping>
    <servlet-name>Push Servlet</servlet-name>
    <url-pattern>/primepush/*</url-pattern>
  </servlet-mapping>
  <context-param>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/META-INF/taglib.xml</param-value>
  </context-param>
  <context-param>
    <param-name>primefaces.SUBMIT</param-name>
    <param-value>partial</param-value>
  </context-param>
  <context-param>
    <param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
    <param-value>65535</param-value><!-- 64KB -->
  </context-param>
  <error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/error.xhtml</location>
  </error-page>
  <session-config>
    <session-timeout>-1</session-timeout>
  </session-config>  
</web-app>
xhtml content

Code: Select all

        <!-- Connection which will receive push notifications from server -->
        <p:socket id="wdaPushing" onMessage="WDA.pushCallbackFunction" onError="WDA.pushErrorFunction" channel="/events/#{session.id}/" /> 

bean code:

Code: Select all

@ManagedBean(name = "DSession")
@SessionScoped
public class DSessionBean {
    public EventBus                  eventBus;
    public String                      session_id;
    public String                       channel;

    @PostConstruct
    public void postInit() {

        session_id  = FacesUtils.getSessionId();
        channel      = "/events/" + session_id  + "/";

        eventBus    = EventBusFactory.getDefault().eventBus();
    }

    public synchronized void makePush(Object   objData){
          eventBus.publish(channel, objData);
    }

}
Stack when break in onOpen:

PushResource.onOpen(RemoteEndpoint, EventBus) line: 35
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43
Method.invoke(Object, Object...) line: 601
Invoker.invokeMethod(Method, Object, Object...) line: 49
PushEndpointHandlerProxy.invokeOpenOrClose(Method, RemoteEndpointImpl) line: 372
PushEndpointHandlerProxy$3.onSuspend(AtmosphereResourceEvent) line: 171
AtmosphereResourceImpl.onSuspend(AtmosphereResourceEvent) line: 640
AtmosphereResourceImpl.notifyListeners(AtmosphereResourceEvent) line: 587
AtmosphereResourceImpl.notifyListeners() line: 564
AtmosphereResourceImpl.suspend(long) line: 383
AtmosphereResourceLifecycleInterceptor.postInspect(AtmosphereResource) line: 119
GlassFishServ30WebSocketSupport(AsynchronousProcessor).postInterceptors(List<AtmosphereInterceptor>, AtmosphereResource) line: 323
GlassFishServ30WebSocketSupport(AsynchronousProcessor).action(AtmosphereRequest, AtmosphereResponse) line: 195
GlassFishServ30WebSocketSupport(AsynchronousProcessor).suspended(AtmosphereRequest, AtmosphereResponse) line: 98
GlassFishServ30WebSocketSupport.service(AtmosphereRequest, AtmosphereResponse) line: 60
AtmosphereFramework.doCometSupport(AtmosphereRequest, AtmosphereResponse) line: 1809
DefaultWebSocketProcessor.dispatch(WebSocket, AtmosphereRequest, AtmosphereResponse) line: 434
DefaultWebSocketProcessor.open(WebSocket, AtmosphereRequest, AtmosphereResponse) line: 187
GlassFishServ30WebSocketSupport$Grizzly2WebSocketApplication.onConnect(WebSocket) line: 144
DefaultWebSocket.onConnect() line: 202
WebSocketEngine.upgrade(FilterChainContext, HttpContent, Mapper) line: 229
WebSocketAddOnProvider$GlassfishWebSocketFilter.doServerUpgrade(FilterChainContext, HttpContent) line: 118
WebSocketAddOnProvider$GlassfishWebSocketFilter(WebSocketFilter).handleServerHandshake(FilterChainContext, HttpContent) line: 319
WebSocketAddOnProvider$GlassfishWebSocketFilter(WebSocketFilter).handleHandshake(FilterChainContext, HttpContent) line: 278
WebSocketAddOnProvider$GlassfishWebSocketFilter(WebSocketFilter).handleRead(FilterChainContext) line: 199
ExecutorResolver$9.execute(Filter, FilterChainContext) line: 119
DefaultFilterChain.executeFilter(FilterExecutor, Filter, FilterChainContext) line: 288
DefaultFilterChain.executeChainPart(FilterChainContext, FilterExecutor, int, int, DefaultFilterChain$FiltersState) line: 206
DefaultFilterChain.execute(FilterChainContext) line: 136
DefaultFilterChain.process(Context) line: 114
ProcessorExecutor.execute(Context) line: 77
TCPNIOTransport.fireIOEvent(IOEvent, Connection, IOEventProcessingHandler) line: 838
AbstractIOStrategy.fireIOEvent(Connection, IOEvent, IOEventProcessingHandler, Logger) line: 113
WorkerThreadIOStrategy.run0(Connection, IOEvent, IOEventProcessingHandler) line: 115
WorkerThreadIOStrategy.access$100(Connection, IOEvent, IOEventProcessingHandler) line: 55
WorkerThreadIOStrategy$WorkerThreadRunnable.run() line: 135
FixedThreadPool$BasicWorker(AbstractThreadPool$Worker).doWork() line: 564
FixedThreadPool$BasicWorker(AbstractThreadPool$Worker).run() line: 544
DefaultWorkerThread(Thread).run() line: 722

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

05 Aug 2014, 20:05

sessionId got <null> ??? hmmm...

Code: Select all

2014-08-04T11:16:30.257-0500|INFO: <ERROR> Push connection not recognized, sessionId got <null>
2014-08-04T11:16:38.545-0500|INFO: Push connection with null sessionId closed
2014-08-04T11:17:24.803-0500|INFO: <ERROR> Push connection not recognized, sessionId got <null>
2014-08-04T11:17:33.008-0500|INFO: Push connection with null sessionId closed
is it possible that sessionId == null, because the HttpSession ended? maybe you can add some logger lines in @PostConstruct and @PreDestroy of your @SessionScoped bean, so we can know when HttpSession is created and destroyed/ended.
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

pslzr
Posts: 11
Joined: 12 Jun 2012, 17:21

06 Aug 2014, 18:04

Have done as you suggest.

Basic SesssionScoped bean changes:

Code: Select all

    @PostConstruct
    public void postInit() {
                .....
		System.out.println("Session started with " + session_id);
    }

    @PreDestroy
    public void preEnd(){
		System.out.println("Session ended with " + session_id);
                .....
    }
And, obtained result for your consideration:

2014-08-06T10:41:32.278-0500|INFO: Session started with bfb80b2f9f8e61d643118747241d
2014-08-06T10:41:33.612-0500|INFO: Tipo de Browser = Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36 Lenguage = 0
2014-08-06T10:41:33.745-0500|INFO: Push connection opened with sessionId bfb80b2f9f8e61d643118747241d
2014-08-06T10:41:41.334-0500|INFO: Push connection closed with sessionId bfb80b2f9f8e61d643118747241d
2014-08-06T10:41:53.214-0500|INFO: Session started with bfbd2ba32409df6bb4b4405b5257
2014-08-06T10:41:53.703-0500|INFO: Tipo de Browser = Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36 Lenguage = 0
2014-08-06T10:41:53.745-0500|INFO: <ERROR> Push connection not recognized, sessionId got <null>
2014-08-06T10:42:06.406-0500|INFO: Push connection with null sessionId closed
2014-08-06T10:43:07.961-0500|INFO: Session ended with bfb80b2f9f8e61d643118747241d
2014-08-06T10:43:48.104-0500|INFO: Session ended with bfbd2ba32409df6bb4b4405b5257
2014-08-06T10:43:55.060-0500|INFO: Session started with bfdaeb1985a5b411247835663f3e
2014-08-06T10:43:55.532-0500|INFO: Tipo de Browser = Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36 Lenguage = 0
2014-08-06T10:43:55.572-0500|INFO: Push connection opened with sessionId bfdaeb1985a5b411247835663f3e
2014-08-06T10:44:05.859-0500|INFO: Push connection closed with sessionId bfdaeb1985a5b411247835663f3e

kukeltje
Expert Member
Posts: 9605
Joined: 17 Jun 2010, 13:34
Location: Netherlands

06 Aug 2014, 18:41

predestroy is not called when the session ends but when the session is actually removed.
http://stackoverflow.com/questions/1474 ... on-expired

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

06 Aug 2014, 20:57

interesting, i just recognized this, below, in your first/initial post,

Code: Select all

  <session-config>
    <session-timeout>-1</session-timeout>
  </session-config>  
i wonder if you will continue to get these errors, if you change your session-timeout value, above.

Code: Select all

2014-08-04T11:16:30.257-0500|INFO: <ERROR> Push connection not recognized, sessionId got <null>
2014-08-04T11:16:38.545-0500|INFO: Push connection with null sessionId closed
2014-08-04T11:17:24.803-0500|INFO: <ERROR> Push connection not recognized, sessionId got <null>
2014-08-04T11:17:33.008-0500|INFO: Push connection with null sessionId closed
maybe you need to do some research following:

glassfish + singleton + http session attributes + session-timeout
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

pslzr
Posts: 11
Joined: 12 Jun 2012, 17:21

07 Aug 2014, 01:00

Thank you for the quote.

So, this would be the conditions
- The url was opened in the browser
2014-08-06T10:41:53.214-0500|INFO: Session started with bfbd2ba32409df6bb4b4405b5257
- The push connection was stablished
2014-08-06T10:41:53.745-0500|INFO: <ERROR> Push connection not recognized, sessionId got <null>
- The browser was closed and the push connection got closed
2014-08-06T10:42:06.406-0500|INFO: Push connection with null sessionId closed
- Session time should be eternal, but, there is a process in server monitoring connections and closing if heartbeat fails.
2014-08-06T10:43:48.104-0500|INFO: Session ended with bfbd2ba32409df6bb4b4405b5257


So.. as the time from closing of the browser to the report is of about 42 seconds.. do you think the session could be "practically" closed at the moment of the opening the push connection???.. that is 2014-08-06T10:41:53.745 ????

I point out this because session appears to be closed 42 seconds later, and pushing is the problem I would like to solve.

Appreciate your help.
Last edited by pslzr on 07 Aug 2014, 16:06, edited 1 time in total.

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

07 Aug 2014, 01:20

please study/review atmosphere framework's wiki web pages. I think there is some type of session support and also heartbeat support too.

https://github.com/Atmosphere/atmospher ... -WebSocket
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

pslzr
Posts: 11
Joined: 12 Jun 2012, 17:21

07 Aug 2014, 01:32

Thank you smithh032772

Before going to Atmosphere and Websockets and implementing a better heartbeat scenario.

As I am implementing using Primefaces, and using push of Primefaces, I would like to solve the problem from that platform, if I need to jump to atmosphere it means I have to solve a Primefaces source code problem or similar, or avoid using push from Primefaces.

If push in that platform is not 100% reliable, my final implementation using this version of Primefaces is totally useless.

Sigh..
Last edited by pslzr on 07 Aug 2014, 16:07, edited 1 time in total.

kukeltje
Expert Member
Posts: 9605
Joined: 17 Jun 2010, 13:34
Location: Netherlands

07 Aug 2014, 09:19

I don't think the problem is caused by push but by some other more generic issue.

Can you check from the browser console and/or network sniffer what requests this client makes to the server? Maybe they indeed have no good session (cookie blocking? or something similar)

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

07 Aug 2014, 16:29

okay, revisiting this below,
pslzr wrote:So, this would be the conditions
- The url was opened in the browser
2014-08-06T10:41:53.214-0500|INFO: Session started with bfbd2ba32409df6bb4b4405b5257
- The push connection was stablished
2014-08-06T10:41:53.745-0500|INFO: <ERROR> Push connection not recognized, sessionId got <null>
- The browser was closed and the push connection got closed
2014-08-06T10:42:06.406-0500|INFO: Push connection with null sessionId closed
- Session time should be eternal, but, there is a process in server monitoring connections and closing if heartbeat fails.
2014-08-06T10:43:48.104-0500|INFO: Session ended with bfbd2ba32409df6bb4b4405b5257


So.. as the time from closing of the browser to the report is of about 42 seconds.. do you think the session could be "practically" closed at the moment of the opening the push connection???.. that is 2014-08-06T10:41:53.745 ????

...
i wonder if the issue is caused by your code below,

Code: Select all

@ManagedBean(name = "DSession")
@SessionScoped
public class DSessionBean {
    public EventBus                  eventBus;
    public String                      session_id;
    public String                       channel;

    @PostConstruct
    public void postInit() {

        session_id  = FacesUtils.getSessionId();
        channel      = "/events/" + session_id  + "/";

        eventBus    = EventBusFactory.getDefault().eventBus();
    }

    public synchronized void makePush(Object   objData){
          eventBus.publish(channel, objData);
    }

}
in my app, I don't do this,

Code: Select all

    @PostConstruct
    public void postInit() {

        ...

        eventBus    = EventBusFactory.getDefault().eventBus();
    }
my PrimeFaces Push is all done in a CDI @ApplicationScoped bean, and FYI, my app is completely CDI and no longer JSF managed beans.

i am doing something very similar to you. each user session will have it's own PrimeFaces Push path. I use user name + session ID, since user can login from multiple devices (desktop/PC, ipad, android) all at the same time (user can have multiple sessions).

i shared my code in this forum months ago (maybe at least 1 year ago). will have to find it, and then you can review and/or do something similar.

EDIT

I searched google for the following:

site:forum.primefaces.org pushnotification userpushingmessage

and I found

Re: Push message when user disconnects?

and

Push with threads
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 46 guests