2015-09-01 49 views
12

我已經爲Vaadin會話設置了最大不活動時間間隔,如下所示。Vaadin會話setMaxInactiveInterval UI響應不一致

VaadinSession.getCurrent().getSession().setMaxInactiveInterval(60); 

添加了會話銷燬偵聽器,如下所示進行測試。

servletService.addSessionDestroyListener(new SessionDestroyListener() { 
    public void sessionDestroy(SessionDestroyEvent event) { 
     System.out.println("SESSION TIMEOUT"); 
    } 
}); 

該監聽器在服務器端的所需時間被調用。 但是我不能同時在瀏覽器端看到「Session Expired」消息。通常它會在4分鐘和5分鐘之間顯示。 有沒有辦法以一致的方式同時獲得這兩個。

另請注意,我們並未使用推送功能,目前它不適合我們。

執行客戶端輪詢會重置會話的上次活動時間,並且如果輪詢時間間隔小於maxInactiveInterval,可以保持會話永久保持活動狀態。

回答

1

以下解決方案在沒有@Push啓用以及沒有任何自定義JS部件的這種情況下爲我工作。 首先在主類中設置maxInactiveInterval,如下所示。僅顯示與此解決方案相關的代碼。

public class MyApplication extends UI { 
     @Override 
     protected void init(VaadinRequest request) { 
VaadinSession.getCurrent().getSession().setMaxInactiveInterval(sessionTimeout); 
    } 

    } 

我們必須默認會話過期消息如下。 Vaadin論壇已經提出這個解決方案,並表示它應該在會話超時15秒內工作。

public class CustomInitServlet extends VaadinServlet { 
     getService().setSystemMessagesProvider(
       new SystemMessagesProvider() { 
        @Override 
        public SystemMessages getSystemMessages(SystemMessagesInfo systemMessagesInfo) { 
         CustomizedSystemMessages customizedSystemMessages = new CustomizedSystemMessages(); 
         customizedSystemMessages.setSessionExpiredMessage(null); 
         customizedSystemMessages.setSessionExpiredCaption(null); 
         customizedSystemMessages.setSessionExpiredNotificationEnabled(true); 
         return customizedSystemMessages; 
        } 
       }); 


// other code 
} 

然後在web.xml加入高心跳間隔,這將是比maxInactiveInterval更高。

<context-param> 
    <param-name>heartbeatInterval</param-name> 
    <param-value>1200</param-value> 
</context-param> 
3

問題:

您的會話在服務器端無效,一切都很好。但問題是,你的客戶從未被通知過這個事件。您必須與服務器進行交互才能獲得會話過期消息,例如按下按鈕,刷新頁面等...

如何解決此問題?

爲了解決這個問題,你有一些解決方案:

  • 使用@Push註釋see Documentation
  • 部隊使用GETPAGE客戶端刷新()重新加載()
  • 變化進行任何操作,會話超時會出現在下一個客戶端動作
  • 在客戶端實施「會話查找」,以便每隔X秒觀察會話是否仍然有效,如果已過期,只需從客戶端調用Page.getCurrent.reload()即可。

小心@Push

根據您正在使用的應用程序服務器上,您可能需要更新,以支持@Push(我不得不與tomcat7,因爲tomcat7不支持的WebSocket)

+0

感謝您的回答,是的我知道問題是客戶端沒有得到通知。但是,我們正在做這個應用程序沒有推。沒有改變也不是一種選擇,因爲它看起來像會話還沒有過期。強制刷新頁面看起來像是一個選項。但我認爲它不適用於已銷燬的會話,因爲沒有「頁面」這樣的內容,因爲沒有客戶端會話。如我錯了請糾正我。 – Don

+0

使用Page.getCurrent()。reload()(更正了我答案中的方法名稱)應刷新客戶端頁面,因爲即使客戶端Session已過期,與它相關的Page對象仍應存在。在我看來,如果沒有推送,您無法正確通知客戶。我添加了另一個解決方案,我可以解決您的問題。 – Supamiu

+0

是的我也想過在客戶端進行輪詢,看看服務器是否還活着。但它不起作用,因爲輪詢服務器將重置會話的最後活動時間,並且因爲該會話永遠不會超時。 – Don

5

Vaadin應用程序在會話生命週期中保持客戶端和服務器端通信。有參數調用心跳間隔與默認值5分鐘(300s)。所以這意味着每隔5分鐘客戶端請求服務器會話仍然存在。這就是爲什麼當Session被銷燬時,你會在控制檯中看到消息,並且只有在一段時間後你才能在瀏覽器中看到Session Expired消息。

您可以更改heartbeatInterval屬性和設置較小的值(單位:秒),但請記住,你需要設置closeIdleSessions =真明確爲好。在下面的例子中,我將此值設置爲1秒。

@VaadinServletConfiguration(heartbeatInterval=1, closeIdleSessions=true, productionMode = false, ui = MyUI.class) 
    public static class Servlet extends VaadinServlet { 
    } 
+0

你也可以在web.xml部署描述符中修改這個間隔:) – Supamiu

+0

@Taras Klym,它需要在服務器端錯過三次熱擊敗會議。在默認情況下,需要15分鐘。該問題中提到的方法已被使用,因爲心跳間隔在部署後不可配置。 – Don

+0

@Don,你幾乎是對的,但心跳有兩個功能:第一個是服務器端的無效會話,如果用戶關閉了應用程序或瀏覽器後3選項錯過了心跳(默認約15分鐘),第二個 - 通知客戶端在服務器上的會話已經在下一次心跳(默認大約5分鐘)時關閉。在你描述的問題中,你有情況#2。會話已經在服務器上被銷燬,並且顯示消息伴隨着下一個心跳。 –