Огонь событие, не влияя ЗК-аут


У меня возникли проблемы с получением таймаута сеанса ZK, потому что наше приложение опрашивает сервер каждые несколько минут для получения информации. Код, который запускает этот опрос, - это Javascript, который нажимает скрытую кнопку, посылая событие onClick на сервер.

Знаете ли вы какой-либо способ сообщить ZK, что этот опрос автоматизирован и не должен влиять на таймер таймаута сеанса?

Большое спасибо.

- Ян

2 4

2 ответа:

Обходной путь-написать фильтр, чтобы определить, является ли запрос запросом опроса, и зарегистрировать время "реального" запроса в фильтре, а затем аннулировать сеанс, если реального запроса нет в течение длительного времени.

Пример:

Тест.Зул

<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>

ЗК.xml

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

Фильтр в сети.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() {}
}

Короткий ответ-нет.

Длинный ответ, Во-первых, нет никакой"сессии ZK". Это просто HttpSession, как определено спецификацией сервлета. Во-вторых, управление сеансами выполняется веб-контейнером сервлета, поэтому сброс счетчика таймаута сеанса выполняется задолго до передачи запроса в ZK для обработки.