Огонь событие, не влияя ЗК-аут
У меня возникли проблемы с получением таймаута сеанса ZK, потому что наше приложение опрашивает сервер каждые несколько минут для получения информации. Код, который запускает этот опрос, - это Javascript, который нажимает скрытую кнопку, посылая событие onClick на сервер.
Знаете ли вы какой-либо способ сообщить ZK, что этот опрос автоматизирован и не должен влиять на таймер таймаута сеанса?
Большое спасибо.
- Ян
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 для обработки.