编程语言
首页 > 编程语言> > java – 偶尔,Vaa​​din不会在“会话超时”消息后使会话无效

java – 偶尔,Vaa​​din不会在“会话超时”消息后使会话无效

作者:互联网

在我的Vaadin应用程序中,当Vaadin在“会话超时”消息后没有使会话无效时,我遇到了问题.收到此消息后,用户有时可以单击链接或刷新页面并继续工作,就好像他们仍在登录一样.
我使用以下参数:

closeIdleSessions=true
heartbeatInterval=60
session-timeout=15

上一个参数(会话超时)也在context.xml(session-timeout = 900)和web.xml(session-config / session-timeout = 15)中设置,因为我没有从vaadin文档中得到清楚,是否有这样的vaadin servlet的参数与否.

有人面对名义上的问题吗?

更新1:固定参数片段.

更新2:当出现Session expired消息时,不会触发SessionDestroyListener.sessionDestroy.

更新3:由于代码错误而出现上一个错误.现在调用SessionDestroyListener.sessionDestroy,但是我无法从给定的事件访问HttpSession.

这是我的SessionDestroyListener代码(请注意if分支中的注释):

private static class SynchronizerSessionDestroyListener implements SessionDestroyListener {
    @Override
    public void sessionDestroy(SessionDestroyEvent event) {
        if (event.getSession() != null){
            WrappedSession wrappedSession = event.getSession().getSession();
            if (wrappedSession instanceof WrappedHttpSession){
                WrappedHttpSession wrappedHttpSession = (WrappedHttpSession) wrappedSession;
                HttpSession httpSession = wrappedHttpSession.getHttpSession();
                if (httpSession != null){
                    try {
                        httpSession.invalidate();
                        logger.debug("Session '{}' was invalidated", httpSession.getId());
                    } catch (IllegalStateException e){
                        // do nothing, already invalidated
                        logger.debug("Session '{}' was already invalidated: {}", httpSession.getId(), e.getMessage());
                    }
                } else {
                    logger.warn("Could not invalidate http session for vaadin session: http session is null"); // THIS IS THE BRANCH WHICH IS ACTUALLY GET EXECUTED ON 'SESSION EXPIRED' MESSAGE: event.getSession().getSession() is null!
                }
            } else {
                logger.warn("Could not invalidate http session for vaadin session: event session is not an http session");
            }
        } else {
            logger.warn("Could not invalidate http session for vaadin session: event session is null");
        }
    }
}

以下是我如何附加监听器:

public class X extends VaadinServlet {
    // different class members
    @Override
    protected void servletInitialized() throws ServletException {
        super.servletInitialized();
        getService().addSessionDestroyListener(new SynchronizerSessionDestroyListener());
    }
}

解决方法:

我将尝试解释会话失效基本上如何工作,也许这有帮助(我无法从你的问题中读取太多信息):

>通常会话将在指定时间内超时
session-timeout参数.
>但你有心跳加速
间隔考虑在内.如果您的心跳间隔较短
比会话超时(通常是),心跳将使会话保持活动状态
永远.
>那是参数closeIdleSessions相关的地方.设置
此参数为true,浏览器不会将心跳作为
有效的超时请求,但最后一次非心跳
请求.
>第二次但是:什么时候会识别超时?客户端引擎只能在心跳或用户采取某些操作时识别此情况(如在两种情况下都对服务器发出请求).因此,当超过指定的超时时,实际的超时不会发生,但是在超时后的下一次心跳时.
>其他情况:在3次心跳丢失后,服务器也会关闭会话.例如.如果浏览器关闭,这将导致会话无效,因为没有发送心跳.

示例web.xml更好地解释:

<context-param>
 <!-- ATTENTION: This value is set in SECONDS -->
 <param-name>heartbeatInterval</param-name>
 <param-value>180</param-value>
</context-param>

<session-config>
  <!-- ATTENTION: This value is set in MINUTES -->
  <session-timeout>4</session-timeout>
</session-config>

<servlet>
    <servlet-name>VaadinServlet</servlet-name>
    <servlet-class>com.example.VaadinServlet</servlet-class>
    <init-param>
      <param-name>closeIdleSessions</param-name>
      <param-value>true</param-value>
    </init-param>
</servlet>

使用上面的web.xml,会话将在6分钟后超时(无需用户交互).

说明:
会话超时设置为4分钟,但4分钟没有心跳.下一次心跳将在6分钟.现在,客户端引擎知道会话实际超时并将显示相应的消息.

我不确定使用Vaadin Push时这是否是相同的过程,因为我们有一个从客户端到服务器的连续通道.

资料来源:
Book of Vaadin – 4.8.7. Session Expiration
Book of Vaadin – 4.9.6. Other Servlet Configuration Parameters, Session Timeout After User Inactivity

附加信息:
即将推出的Vaadin 7.6似乎可以改善客户端 – 服务器连接的稳定性:Blog Post

标签:java,session,vaadin,session-timeout
来源: https://codeday.me/bug/20190722/1504058.html