我有一个应用程序,其中用户经常让页面整天在浏览器中运行。该页面有一个间隔渲染,每 30 秒更新一次数据。
但是,如果用户有一段时间没有与页面交互,它仍然会过期。只要浏览器打开并发出预定的请求,我希望它自动扩展。
每次为这些页面之一触发预定的渲染器时,是否有一种方法可以自动扩展会话?
当我的代码已经被 ICEFaces 每 30 秒调用一次时,我真的不想做 Javascript 黑客来单击按钮。ICEFaces 内部计时器的以下黑客解决方法似乎有效:
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.2RC1(可能最终也会使用 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>
ICEfaces 有一个保持会话活动的内部机制(该机制有时被称为“心跳”)。您可以查看相关文档并在web.xml中配置提到的参数(尤其是heartbeatInterval和heartbeatTimeout)。
Iceface's Ajax bridge has callback APIs, for example Ice.onSessionExpired()
which you may be able to use.
<body id="document:body">
<script type="text/javascript">
Ice.onSessionExpired('document:body', function() {
<!-- Do something here -->
});
</script>
See http://www.icefaces.org/docs/v1_8_0/htmlguide/devguide/references4.html#1094786 for more details.
如果我不明白您的真正目的是什么,那么您需要一种计时器,它会自动扩展每个用户会话客户端,从而覆盖服务器端默认页面会话到期时间(通常为 30 分钟,仅用于详细说明,因为我了解脚本如果用户在页面上处于活动状态,则每 30 秒“呈现”一次)。
如果这么好,在 JSF 之前,我总是通过地下 Javascript 扩展非活动用户会话,所以我也会在你的情况下使用它。实际上,您可以从以下开始在 Javascript 中构建一个简单的页面侦听器:
window.setInterval( expression , msecIntervalTiming );
“表达式”可以是一个被调用的函数,您可以在其中调用一些虚拟 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”作为全局参考来跟踪侦听器状态,因此当您需要激活“自动扩展”时,您可以为其分配一个 setInterval。相反,当用户返回页面(由您知道的某个事件触发)时,您清除停止侦听器轮询的超时。上面的例子显然暗示了用户回来后必须手动重新加载页面。
但是,在您的特定情况下,我将避免干扰 Icefaces 框架自动生成的 javascript。即使对于 ipothesys,您可以定期在不可见的输入元素上模拟一些用户事件(样式设置在 "visibility: hidden" 上,绝对不在 "display: none" 上),这也会导致 Icefaces 事件不会停止它并使自己工作不断地
<input type="button" name="invisivleButton" value="..." style="visibility: hidden, z-index: 0;" 等元素 /> 您可以在其上定期调用单击事件
document.forms["YourDummyForm"]["invisivleButton"].click();
有关用法,请参阅 Devedge Online 的旧 JS 文档 :-)
http://devedge-temp.mozilla.org/library/manuals/2000/javascript/1.3/reference/window.html#1203669