Watch, Follow, &
Connect with Us

Welcome, Guest
Guest Settings
Help

Thread: Session timeout form



Permlink Replies: 7 - Last Post: Apr 19, 2017 12:48 PM Last Post By: S. Mahaux
S. Mahaux

Posts: 32
Registered: 4/4/02
Session timeout form
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 3, 2017 10:52 AM
When a session times out, I'd like to clear the user's personal data by showing a 'session timed out' form.
How can I do this?
I did a forum search but nothing found. I don't see an event, the session destructor is too late, a timer creates activity which prevents a timeout.
Thanks for your input.
S. Mahaux

Posts: 32
Registered: 4/4/02
Re: Session timeout form
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 4, 2017 9:44 AM   in response to: S. Mahaux in response to: S. Mahaux
There's gotta be a way to clear the browser of the user's data at the end of a session.
S. Mahaux

Posts: 32
Registered: 4/4/02
Re: Session timeout form
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 4, 2017 9:45 AM   in response to: S. Mahaux in response to: S. Mahaux
There's gotta be a way to clear the browser of the user's data at the end of a session.
Alexandre Machado

Posts: 1,576
Registered: 8/10/13
Re: Session timeout form
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 5, 2017 3:15 PM   in response to: S. Mahaux in response to: S. Mahaux
S. Mahaux wrote:

When a session times out, I'd like to clear the user's personal data
by showing a 'session timed out' form. How can I do this?
I did a forum search but nothing found. I don't see an event, the
session destructor is too late, a timer creates activity which
prevents a timeout. Thanks for your input.

"Clear user's personal data"

I believe you are referring to browser side data?

If so, you must use JavaScript for that.

There is a demo showing how to do session countdown:

https://iwdemos.codeplex.com/SourceControl/latest#Atozed
Demos/XIV/Delphi/SessionCountDown/

You can use that same JavaScript as a starting point. Instead of
updating text on the user page, you can just clear the data when the
timer reaches zero.
S. Mahaux

Posts: 32
Registered: 4/4/02
Re: Session timeout form
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 7, 2017 3:33 PM   in response to: S. Mahaux in response to: S. Mahaux
By "Clear user's personal data"
I mean don't leave the user's data displayed in the browser after the timeout. Displaying the initial form would be acceptable.

The problem with the JavaScript timer is that it would have to be reset every time the IntraWeb timer is reset so they match.

There is already a TIWServerControllerBase::OnCloseSesson
It sure would be convenient if there was a TIWServerControllerBase::BeforeCloseSession

Edited by: S. Mahaux on Apr 7, 2017 3:33 PM
Soren Hartig

Posts: 13
Registered: 7/17/04
Re: Session timeout form
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 9, 2017 2:27 AM   in response to: S. Mahaux in response to: S. Mahaux
S. Mahaux wrote:
By "Clear user's personal data"
I mean don't leave the user's data displayed in the browser after the timeout. Displaying the initial form would be acceptable.

The problem with the JavaScript timer is that it would have to be reset every time the IntraWeb timer is reset so they match.

There is already a TIWServerControllerBase::OnCloseSesson
It sure would be convenient if there was a TIWServerControllerBase::BeforeCloseSession

Edited by: S. Mahaux on Apr 7, 2017 3:33 PM

I think you can use this link http://blog.kassebaum.eu/?p=105
S. Mahaux

Posts: 32
Registered: 4/4/02
Re: Session timeout form
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2017 12:48 PM   in response to: Soren Hartig in response to: Soren Hartig
Thanks for the link.
S. Mahaux

Posts: 32
Registered: 4/4/02
Re: Session timeout form
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2017 12:46 PM   in response to: S. Mahaux in response to: S. Mahaux
Here's what I ended up doing. Similar concept then Roman's blog post that Soren linked to.
1. Update a time stamp in the base form.
2. Set a timer in the base form.
3. display a message & URL which works even after the session has ended.

ServerController.cpp
~~~~~~~~~~~~~~
void __fastcall TIWServerController::IWServerControllerBaseAfterDispatch(THttpRequest *Request, THttpReply *aReply)
{
    TIWFormBase::ServerController_AfterDispatch( Request, aReply ) ;
}//IWServerControllerBaseAfterDispatch()
//---------------------------------------------------------------------------

IWForm_Base.h
~~~~~~~~~~~~

class TIWFormBase: public TIWAppForm
{
__published:
...
    TIWTimer *SessionTimer;
    void __fastcall SessionTimerAsyncTimer(TObject *Sender, TStringList *EventParams);
 
public:
    static TNotifyEvent  onSessionTimeout ;
    static void __fastcall ServerController_AfterDispatch( THttpRequest* request, THttpReply* reply ) ;
 
    __fastcall TIWFormBase( TComponent* Owner ) ;
    __fastcall ~TIWFormBase() ;
 
protected:
    TDateTime  session_lastAccess_ ;
 
private:
...
};

IWForm_Base.cpp
~~~~~~~~~~~~~~

TNotifyEvent  TIWFormBase::onSessionTimeout = NULL ;
//---------------------------------------------------------------------------
 
void __fastcall TIWFormBase::ServerController_AfterDispatch( THttpRequest* request, THttpReply* reply )
// Call from TIWServerControllerBase::OnAfterDispatch().
// Static, public.
// Warning: Called from a different thread.
// Note: Works in conjunction with TIWFormBase::SessionTimerAsyncTimer().
{
    if( ::WebApplication == NULL )
        return ;
 
    // Ignore ALL timers since they are not part of the USER activity.
    // Note: Timers only fire in the ACTIVE form.
    //       Timers can prevent the session from timing out.
    if( request->Query.UpperCase().Pos("TIMER") )
        return ;
 
    TIWFormBase* activeForm = dynamic_cast<TIWFormBase*>( ::WebApplication->ActiveForm ) ;
    if( activeForm )
        // Don't use 'TWebApplication::LastAccess', which includes timer activity.
        activeForm->session_lastAccess_ = Now() ;
}//ServerController_AfterDispatch()
//--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
 
void __fastcall TIWFormBase::SessionTimerAsyncTimer(TObject *Sender, TStringList *EventParams)
// Published event handler.
// Note: Works in conjunction with TIWFormBase::ServerController_AfterDispatch().
{
    if( SessionTimer->Tag )
        return WebApplication->TerminateAndRedirect( WebApplication->ApplicationURL ) ;
 
    SessionTimer->Enabled  = false ;
 
    // About to timeout?
    // Note: Don't use 'TWebApplication::LastAccess', which inculdes timer activity.
    TDateTime now    = Now() ;
    TDateTime timeout( 0, WebApplication->SessionTimeOut/*minutes*/, 0, 0 ) ;
    timeout += session_lastAccess_ ;
    timeout -= TTime( 0, 0, 10/*seconds*/, 0 ) ; //Must process BEFORE the actual timeout.
    if( timeout > now )
    {
        // Set timer to next timeout.
        // Note: This method fires less often then regular intervals.
        int remaining = SecondsBetween( timeout, now ) ;
        SessionTimer->Interval = remaining * 1000 ;
        SessionTimer->Enabled  = true ;
        return ;
    }//if reset
 
    // Clear user's sensitive data from the browser.
    if( onSessionTimeout )
    {
        // Warning: If a new form is created,
        //          then this form's events & timers won't fire anymore.
        onSessionTimeout( this ) ;
    }//if custom handler
    else
    {
        WebApplication->ShowMessage("Session timed-out!") ;
 
        // Give user a chance to read the message
        // before TerminateAndRedirect().
        SessionTimer->Tag      = 1 ; //Flag to clear & reload
        SessionTimer->Interval = 5 * 1000 ;
        SessionTimer->Enabled  = true ;
    }//if default handling
}//SessionTimerAsyncTimer()
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
__fastcall TIWFormBase::TIWFormBase( TComponent* owner )
: TIWAppForm         ( owner )
, question_          ( 0 )
, session_lastAccess_( Now() )
{
    // Set 'SessionTimer'.
    if( SessionTimer->OnAsyncTimer )
        SessionTimerAsyncTimer( NULL, NULL ) ;
...
}//Ctr

Optionally, a project-specific form can be displayed.
SessionTimeOut_IWForm.cpp
~~~~~~~~~~~~~~~~~~~~~~

namespace
{
    class UnitSetup
    {
        public:
            UnitSetup()
            {
                TIWFormBase::onSessionTimeout = OnSessionTimeout ;
            }//Constructor
            //---------------------------------------------------------------
 
            void __fastcall OnSessionTimeout( TObject* sender )
            {
                new TSessionTimedOutForm()->Show() ;
            }//OnSessionTimeout()
            //---------------------------------------------------------------
    } unitSetup_U ;
};//anonymous namespace
//===========================================================================
 
__fastcall TSessionTimedOutForm::TSessionTimedOutForm( void )
: TIWFormBase        ( WebApplication )
{
    Restart_URL->URL                 = WebApplication->ReferringURL ;
    Restart_URL->TerminateApp        = true ;
    Restart_URL->TargetOptions->Mode = tmSelf ;
}//Constructor
//---------------------------------------------------------------------------
 
void __fastcall TSessionTimedOutForm::Restart_URLHTMLTag(TObject *ASender, TIWHTMLTag *ATag)
{
    // Link must work in the browser even when session has ended.
    ATag->Params->Values["href"] = Restart_URL->URL ;
}
//---------------------------------------------------------------------------
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02