4

アプリケーションが数分ごとにサーバーに情報をポーリングするため、ZK セッションのタイムアウトが発生しません。このポーリングをトリガーするコードは、非表示のボタンをクリックして onClick イベントをサーバーに送信する Javascript です。

このポーリングが自動化されており、セッション タイムアウト タイマーに影響を与えるべきではないことを ZK に伝える方法を知っていますか?

どうもありがとう。

-イアン

4

2 に答える 2

3

簡単な答えはノーです。

長い答えは、まず第一に「ZK セッション」がないということです。これは、サーブレット仕様で定義されている単なる HttpSession です。次に、セッション管理はサーブレット Web コンテナによって行われるため、リクエストが処理のために ZK に渡されるずっと前に、セッション タイムアウト カウンタのリセットが行われます。

于 2013-01-03T02:13:13.027 に答える
3

回避策は、リクエストがそのポーリング リクエストであるかどうかを検出するフィルタを作成し、「実際の」リクエストの時間をフィルタに記録してから、長時間実際のリクエストがない場合はセッションを無効にすることです。

サンプル:

test.zul

<zk>
    <intbox id="ibx" value="1" />
    <timer delay="1000" id="pooltimer" repeats="true">
        <attribute name="onTimer"><![CDATA[
            ibx.setValue(ibx.getValue() + 1);
        ]]></attribute>
    </timer>
    <button label="click or invalidated in 20 seconds">
        <attribute name="onClick"><![CDATA[
            long lastRealRequest = (Long)Sessions.getCurrent().getAttribute("LAST_REAL_REQUEST");
            alert("only pooling request in "
                    + ((System.currentTimeMillis() - lastRealRequest) / 1000)
                    + " second(s)");
        ]]></attribute>
    </button>
</zk>

zk.xml

<zk>
    <session-config>
        <session-timeout>20</session-timeout>
    </session-config>
</zk>

web.xml のフィルタ

<filter>
    <filter-name>requestFilter</filter-name>
    <filter-class>test.RequestFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>requestFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

RequestFilter.java

package test;

import java.io.IOException;
import java.util.Map;

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;





public class RequestFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest)request;
        Map param = req.getParameterMap();
        HttpSession sess = req.getSession();
        boolean isRealRequest = true;
        // here detect whether it is the poll request
        // initiate the LAST_REAL_REQUEST if the poll request is
        // the first request
        //
        // invalidate session if no real request within session timeout range
        for (Object key : param.keySet()) {
            if (key.toString().startsWith("cmd")
                && "onTimer".equals(((String[])param.get(key))[0])) {
                // not real request
                isRealRequest = false;
                // try get last real request time
                Long lastRealRequest = (Long)sess.getAttribute("LAST_REAL_REQUEST");
                if (lastRealRequest == null) {
                    System.out.println("init");
                    // init if no previous real request
                    lastRealRequest = System.currentTimeMillis();
                    sess.setAttribute("LAST_REAL_REQUEST", lastRealRequest);
                } else if ((System.currentTimeMillis() - lastRealRequest) > 20000) {
                    System.out.println("invalidate");
                    // invalidate session if only poll request for a long time
                    sess.invalidate();
                }
            }
        }

        // process request
        chain.doFilter(request, response);

        // update LAST_REAL_REQUEST if this is a real request
        if (isRealRequest) {
            // record last real request time
            sess.setAttribute("LAST_REAL_REQUEST", System.currentTimeMillis());
        }
    }
    @Override
    public void destroy() {}
}
于 2013-01-03T08:21:50.200 に答える