Java ICEFaces会话自动扩展

Java ICEFaces会话自动扩展,java,tomcat,jsf,icefaces,java-ee-5,Java,Tomcat,Jsf,Icefaces,Java Ee 5,我有一个应用程序,其中用户经常让页面整天在浏览器中运行。页面有一个间隔,每隔30秒更新一次数据 但是,如果用户有一段时间没有与页面交互,页面仍然会过期。我想它自动扩展,只要浏览器打开并发出预定请求 是否有一种方法可以在每次为其中一个页面触发定时呈现程序时自动扩展会话?如果我不知道您的真正目的是什么,那么您需要一种计时器,它可以自动扩展每个用户会话客户端,从而覆盖服务器端默认的页面会话过期时间(通常为30分钟,仅用于详细说明,因为我知道如果用户在页面上处于活动状态,脚本每30秒“呈现”) 如果是这

我有一个应用程序,其中用户经常让页面整天在浏览器中运行。页面有一个间隔,每隔30秒更新一次数据

但是,如果用户有一段时间没有与页面交互,页面仍然会过期。我想它自动扩展,只要浏览器打开并发出预定请求


是否有一种方法可以在每次为其中一个页面触发定时呈现程序时自动扩展会话?

如果我不知道您的真正目的是什么,那么您需要一种计时器,它可以自动扩展每个用户会话客户端,从而覆盖服务器端默认的页面会话过期时间(通常为30分钟,仅用于详细说明,因为我知道如果用户在页面上处于活动状态,脚本每30秒“呈现”)

如果是这样的话,在JSF之前,我总是通过地下Javascript扩展非活动用户会话,因此我也将在您的案例中使用它。实际上,您可以从以下开始使用Javascript构建一个简单的页面侦听器:

window.setInterval( expression , msecIntervalTiming );
“expression”可以是一个被调用的函数,在该函数中,您可以调用一些伪JSF,以保持会话的活动性,而无需重新加载用户访问的当前页面。过去,我使用标准框架或iframe进行http调用,现在使用XHR/Ajax也更简单

Javascript示例:

var timerID = null;
function simplePageListener() { // invoked by some user event denoting his absence status
    // here goes all events and logic you need and know for firing the poller...
    if (timerID == null) // avoid  duplicates
        timerID = window.setInterval( "window.startPoller()", msecIntervalTiming );
}
//...
function pollerStart() {
  // make iframe or ajax/xhr requests
}
function pollerStop() {
  // make action like page reloading or other needings
}
//...
function triggeredCleanTimer(timer) { // invoked by some user event denoting his active status
  clearTimeout(timer); // it can be also the global variable "timerID"
  timerID = null;
}
实际上,您使用“timerID”作为全局引用来跟踪侦听器状态,因此当您需要激活“autoextension”时,您可以为其分配一个setInterval。相反,当用户返回页面时(由您知道的某个事件触发),则清除停止侦听器轮询的超时。上述示例显然意味着用户返回时必须手动重新加载页面

但是,在您的具体情况下,我将避免干扰Icefaces框架自动生成的javascript。即使对于ipothesys,您可以在不可见的输入元素上定期模拟一些用户事件(样式设置为“可见性:隐藏”,而不是“显示:无”
),这会导致Icefaces事件无法停止它并使其自身继续工作

元素,您可以通过它定期调用click事件

 document.forms["YourDummyForm"]["invisivleButton"].click();
有关用法,请参阅Devedge Online的旧的优秀JS文档:-)


ICEfaces有一个内部机制来保持会话活动(该机制有时被称为“心跳”)。您可以在web.xml中查看并配置所提到的参数(尤其是heartbeatIntervalheartbeatTimeout

Iceface的Ajax桥具有回调API,例如
Ice.onSessionExpired()
,您可以使用这些API

<body id="document:body">
    <script type="text/javascript">
        Ice.onSessionExpired('document:body', function() {
            <!-- Do something here -->
        });
    </script>

Ice.onSessionExpired('document:body',function()){
});

有关更多详细信息,请参阅。

当我的代码已经被ICEFaces每隔30秒调用一次时,我真的不想通过Javascript黑客来点击按钮。以下针对ICEFaces internal timer的黑客解决方案似乎有效:

  private void updateSessionExpiration () {
      HttpSession sess = getSession();
      if (sess != null) {
        try {
            Field fld = SessionDispatcher.class.getDeclaredField("SessionMonitors");
            fld.setAccessible(true);
            Map map = (Map)fld.get(null);
            String sessID = sess.getId();
            if (map.containsKey(sessID)) {
                log.info("About to touch session...");
                SessionDispatcher.Monitor mon = 
                     (SessionDispatcher.Monitor)map.get(sessID);
                mon.touchSession();
            }
        } catch (Exception e) {
            log.error("Failed to touch session");
        }
      }
  }
此外,在ICEFaces 1.8.2的发行版中(可能最终也是如此),有两个新的解决方案可用:

HttpServletRequest request = (HttpServletRequest) servletRequest; 
HttpSession session = request.getSession(); 
if (session != null) { 
    SessionDispatcher.Monitor.lookupSessionMonitor(session).touchSession(); 
} 
或者,将其放在web.xml中,以便在特定模式中的URL命中时进行更新:

<filter> 
    <filter-name>Touch Session</filter-name> 
    <filter-class>com.icesoft.faces.webapp.http.servlet.TouchSessionFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>Touch Session</filter-name> 
    <url-pattern>/seam/remoting/*</url-pattern> 
</filter-mapping> 

接触会话
com.icesoft.faces.webapp.http.servlet.TouchSessionFilter
接触会话
/接缝/远程处理/*

这种内部机制不是为了让会话保持活动状态,而是为了检测会话何时死亡。间隔只是控制客户端以交互方式检测死亡的方式,但它们实际上并没有扩展会话。我面临着类似的问题。你把上面的代码放在哪里?Thanks@Tam-将其放在icefaces定期调用的任何方法中(例如,在RenderManager调用的方法中)