2015-09-01 73 views
12

Ho impostato l'intervallo inattivo massimo per la sessione Vaadin come segue.Set di sessione Vaadin SetMaxInactiveInterval Risposta all'interfaccia utente incoerente

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

Aggiunta una sessione di ascolto come segue per il test.

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

Questo listener viene chiamato all'ora desiderata sul lato server. Tuttavia, non riesco a vedere il messaggio "Sessione scaduta" sul lato browser contemporaneamente. Normalmente viene visualizzato tra il 4 ° e il 5 ° minuto. C'è un modo per ottenere entrambi questi allo stesso tempo in modo coerente.

Si noti inoltre che non stiamo utilizzando push e non è un'opzione per noi al momento.

L'esecuzione del polling lato client reimposta l'ultima ora attiva delle sessioni e può mantenere la sessione attiva per sempre se l'intervallo di polling è inferiore a maxInactiveInterval.

risposta

1

seguente soluzione ha funzionato per me in questo scenario di non avere @Push abilitato così come, senza alcun widget personalizzati js. Primo set maxInactiveInterval come segue nella classe principale. Mostrando solo il codice relativo a questa soluzione.

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

    } 

Abbiamo impostato il messaggio di sessione scaduto come segue. Questo è stato suggerito in un forum Vaadin come soluzione e ha detto che dovrebbe funzionare entro 15 secondi dal timeout della sessione.

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 
} 

Poi nel web.xml aggiunti alta battito cardiaco intervallo che sarà superiore al maxInactiveInterval.

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

Il problema:

La sessione viene invalidata sul lato server, tutto è buono. Ma il problema è che il tuo cliente non viene mai informato di questo evento. Devi fare un'interazione con il server per ottenere un messaggio Sessione scaduta, come premere il pulsante, aggiornare la pagina, ecc ...

Come risolvere il problema?

Per risolvere questo problema, è necessario alcune soluzioni:.

  • Usa @Push annotazione see Documentation
  • Forza aggiornamento lato client utilizzando getPage() reload()
  • Change nulla e la vostra timeout della sessione sarà appare sulla prossima azione lato client
  • Implementare una "Session lookup" sul lato client per guardare ogni X secondi se la sessione è ancora valida, se è scaduta, chiama semplicemente Page.getCurrent.reload() dal lato client.

attenzione con @Push

A seconda del server di applicazione che si sta utilizzando, potrebbe essere necessario aggiornarlo per sostenere @Push (ho dovuto con tomcat7, perché tomcat7 non supporta WebSocket)

+0

grazie per la risposta, sì, so che il problema è lato client non viene notificato. Comunque stiamo facendo l'app senza Push. Anche la modifica di nulla non è un'opzione poiché sembra che la sessione non sia scaduta. Forzare un aggiornamento della pagina sembra un'opzione. Ma penso che non funzionerà con una sessione distrutta, dal momento che non esiste questo tipo di "Pagina" poiché non esiste una sessione client. Correggimi se sbaglio. – Don

+0

L'utilizzo di Page.getCurrent(). Reload() (corretto il nome del metodo nella mia risposta) dovrebbe aggiornare la pagina client perché anche se la sessione client è scaduta, l'oggetto Page relativo ad esso deve ancora esistere. Secondo me, senza Push non è possibile notificare correttamente il client. Ho aggiunto un'altra soluzione che ho appena trovato nel caso in cui possa risolvere il tuo problema. – Supamiu

+0

sì, ho anche pensato di eseguire il polling sul lato client per vedere se il server è ancora vivo. Ma non funzionerà dal momento che il polling server resetterà l'ultimo orario attivo della sessione e, a causa di quella sessione, non verrà mai scaduto. – Don

5

L'applicazione Vaadin mantiene le comunicazioni lato client e lato server durante il ciclo di vita della sessione. Vi sono parametri chiamate heartbeatInterval con valore predefinito 5 minuti (300s). Quindi significa che ogni 5 minuti lato client chiedono al server se la sessione è ancora in vita. Ecco perché, quando Session viene distrutta, vedi il messaggio in Console e solo dopo un certo periodo di tempo vedi il messaggio Session Expired in un Browser.

È possibile modificare heartbeatInterval proprietà e impostare il valore più piccolo (in secondi), ma ricorda che è necessario impostare closeIdleSessions = true esplicitamente pure. Nell'esempio seguente, imposto questo valore su 1 secondo.

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

Puoi anche modificare questo intervallo nel descrittore di distribuzione web.xml :) – Supamiu

+0

@Taras Klym, richiede tre colpi di calore persi sul server per invalidare la sessione. Nel caso predefinito ci vogliono 15 minuti. È stato utilizzato l'approccio menzionato nella domanda, poiché heartbeatinterval non è configurabile dopo la distribuzione. – Don

+0

@Don, hai quasi ragione, ma il battito del cuore ha due funzioni: la prima è una sessione invalida sul lato server se l'utente chiude la scheda con l'applicazione o il browser dopo 3 battito cardiaco mancato (di default intorno ai 15 minuti) e il secondo - notifica Lato client quella sessione sul Server è stata chiusa al prossimo heart-beat (di default intorno ai 5 minuti). Nel problema che descrivi hai la situazione n. 2. La sessione è stata distrutta sul server e mostra il messaggio con il prossimo battito cardiaco. –