5 Replies Latest reply on Mar 20, 2013 4:58 AM by rudresh_mr

    a4j:push and sessionTimeout

    nimo22

      According to http://java.net/jira/browse/ATMOSPHERE-53 session-timeout works when defined in web.xml.

       

      I have that in web.xml

       

      <session-config>

        <session-timeout>4</session-timeout>

      </session-config>

       

      <context-param>

          <param-name>org.atmosphere.useBlocking</param-name>

          <param-value>true</param-value>

      </context-param>

       

      Unfortunately, session timeout will not occur, hence, session will last endlessly. In Firebug, I can see, that RF makes get-requests periodically.

       

      Am I missed something or does RF ignores my session timeout when using a4j:push ?

       

      I am using RF 4.2.1, JBOSS AS 7.1.1.

        • 1. Re: a4j:push and sessionTimeout
          ultrapod

          Seconding this issue.  I'm using RichFaces 4.2.2, JBoss 7.1.1, and Atmosphere 0.8.4 per this wiki article.  The upshot of this is that using a4j:push on a given page seems to eliminate the possibility of session expiration for as long as that page is open, which is a problem for me.  I'm not 100% certain that this is strictly a RichFaces issue, but seeing as how the Atmosphere project closed this issue as of version 0.6.2, im inclined to think it is.

          • 2. Re: a4j:push and sessionTimeout
            ultrapod

            Here's my sledgehammer approach to solving this problem - a custom Filter that is able to distinguish between Push Servlet requests and any other requests.  Anything other than a Push Servlet request will reset the "last accessed" time of the current session.  For every request the filter checks the current time against the "last accessed" time that it maintains; if the difference between the current time and the "last accessed" time is equal to or greater than the session timeout, the session gets invalidated.  The drawbacks to this approach should be evident, but it seems to work reasonably well so far in my low-intensity environment.

             

            The Filter:

             

            import java.io.IOException;
            import java.util.Date;
            import java.util.concurrent.ConcurrentHashMap;
            import java.util.concurrent.TimeUnit;
            
            import javax.servlet.Filter;
            import javax.servlet.FilterChain;
            import javax.servlet.FilterConfig;
            import javax.servlet.ServletException;
            import javax.servlet.ServletRequest;
            import javax.servlet.ServletResponse;
            import javax.servlet.http.HttpServletRequest;
            import javax.servlet.http.HttpSession;
            
            import org.apache.commons.lang.StringUtils;
            import org.apache.log4j.Logger;
            
            
            public class RichfacesPushTimeoutFilter implements Filter
            {
                private final Logger logger = Logger.getLogger(this.getClass().getName());
            
                private static final String pushServletURLMapping = "__richfaces_push";
            
                private ConcurrentHashMap<String, Long> sessionLastAccessedMap = new ConcurrentHashMap<String, Long>();
            
                public void init(FilterConfig arg0) throws ServletException
                {
                    logger.info("init()");
                }
            
                public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
                {
                    if (request instanceof HttpServletRequest == true)
                    {            
                        HttpServletRequest httpServletRequest = (HttpServletRequest)request;
            
                        HttpSession session = httpServletRequest.getSession(false);
            
                        String sessionId = session.getId();
                        Integer sessionMaxActiveInterval = session.getMaxInactiveInterval();  // seconds
                        String requestURI = httpServletRequest.getRequestURI();
                        Long now = new Date().getTime(); // milliseconds
            
                        // do a manual timeout check, regardless of the request
                        if (sessionLastAccessedMap.containsKey(sessionId) == true)
                        {
                            Long lastAccessed = sessionLastAccessedMap.get(sessionId);
            
                            // if the difference between now and lastAccessed is >= the maxActiveInterval, invalidate the session
                            long millisecondsDifference = now - lastAccessed;
            
                            //long secondsDifference = millisecondsDifference/1000;
                            long secondsDifference = TimeUnit.SECONDS.convert(millisecondsDifference, TimeUnit.MILLISECONDS);
            
                            // if the difference between now and lastAccessed is >= the maxActiveInterval, invalidate the session
                            if (secondsDifference >= sessionMaxActiveInterval.longValue() == true)
                            {
                                logger.info("timeout reached, invalidating session: " + sessionId);
                                session.invalidate();
                            }                
                        }
            
                        if (StringUtils.contains(requestURI, pushServletURLMapping) == false)
                        {
                            // if NOT a request for the push servlet, update the last accessed map
                            sessionLastAccessedMap.put(sessionId, now);
                        }
            
                    }
            
                    chain.doFilter(request, response);
                }
            
            
                public void destroy()
                {
                    logger.info("destroy()");
                }
            
            }
            

             

            Add these to your web.xml:

             

             <filter>
              <filter-name>RichfacesPushTimeoutFilter</filter-name>
              <filter-class>your.package.name.here.RichfacesPushTimeoutFilter</filter-class>
             </filter>
            

             

             <filter-mapping>
              <filter-name>RichfacesPushTimeoutFilter</filter-name>
              <url-pattern>*</url-pattern>
             </filter-mapping>
            
            • 3. Re: a4j:push and sessionTimeout
              healeyb

              Nicely done, has anyone logged an issue for this yet? if so it would be an idea to add this filter code to it.

              • 4. Re: a4j:push and sessionTimeout
                ultrapod

                Not that I'm aware of, but my search-fu generally fails me in JIRA-land.  From looking around this forum and the responses of the Richfaces representatives and others, it seems to me as if this behavior of <a4j:push> (and <a4j:poll> for that matter) is generally regarded as a feature, not a bug.

                • 5. Re: a4j:push and sessionTimeout
                  rudresh_mr

                  Integer sessionMaxActiveInterval = session.getMaxInactiveInterval();  //seconds

                  __richfaces_push request returns session max active interval as -1; why is it, it should take session time out from session config which is configured,  but when a4j:push request happned this returns -1 and immediately session invalidated.