Best Practices for Ending a Session

I am trying to understand the best way to close a session. Right now, I am just letting Xojo figure out when to close a session; namely, 3 minutes of no activity or closing the browser/tab running the app. I don’t think this default behavior is working as designed. I can see the session turning off in Google Analytics Real-Time Locations view after about 5.5 minutes of no activity (or after closing the tab running the app) but if I go back to the tab running the app I can still continue from where I left off.

Here are some things I think I might need to do:

  1. Final page in app should navigate to a separate URL outside of the app. Use Session.Quit then ShowURL
  2. Use Session.Timeout to set the amount of inactivity that closes the app. Do you add Session.Quit when this event fires?
  3. Set all properties in Session to nil (not sure this is needed if 1 and 2 are implemented)
  4. Don’t reference properties in Session
  5. Close databases
  6. Don’t use App.SessionCount or App.SessionAtIndex because these might cause session to stay open.

Am I missing anything?

How does session end if there was a crash? If app crashes leave ghost sessions on the server, my workaround for that is to periodically restart the service (Note: We are using a Windows server).

Right now, I am thinking of using #1 and #2 (and I am not using a database). For example, I plan to add an exit button on the final page that navigates to a URL away from the app completely. I am not doing this now because the final page is just a page in the app.

I am using version 2014r2.1.

Depending on the browser you are using, keeping the Tab open still means that the Session is open. Javascript still runs (albeit slowly on browsers like Safari to save power), so the app can still talk to it. As far as the 5.5 minutes, that may be when your browser finally decides that you’re not coming back. I could certainly see some programmer selecting 333 seconds, just to be cute.

No. Calling Session.Quit will kill off the session immediately, from the server side. The ShowURL may never make it to the browser (even if you do it in the other order, I have my doubts)

All Session.Timeout does is set a timer on the browser side to fire the Session.TimedOut event for the current Session. This only means that users haven’t moved their mouse or typed anything during the time interval. If the user moves the tab to the background, it is still counted. Typically I suggest showing a dialog in this event (the first time) which says “You’ve been inactive for xxx minutes. Click OK to continue. You will be automatically logged off in one minute.” and then set Session.Timeout to 60. When that timeout occurs, then call ShowURL to redirect the user back to a login page or one that says “You have been logged off due to inactivity”. It’s very important to tell the user why they were disconnected, otherwise they’ll think it’s some sort of bug.

This depends largely on your app. If you properties refer to other objects it’s probably not a bad idea to have a cleanup routine that does this.

This is not specifically necessary… just be careful that you don’t create circular references (A => B and B => A). If you need this capability, make sure one of them is a WeakRef.

Absolutely.

App.SessionCount won’t hurt you. It’s an Integer and will only ever be sent by value. App.SessionAtIndex you just need to be careful with because the returned values are sent by reference. You can use the Session info temporarily (like if you’re looping through Sessions to push out a global message), but storing the value somewhere without a WeakRef will get you into trouble every time.

Sessions are completely tracked within the app by default. If the app crashes, all of the Sessions immediately die.

Awesome response! Thanks Greg.

Followup questions/comments:

  1. Is there ever a reason to use Session.Quit?
  2. Does the login page or the “You have been logged off due to inactivity.” page have to be outside of the app for the session to shutdown?
  3. I have read in a couple of places on the forum that there is a default 3 minute session shutdown due to inactivity. Is that true? If so, what could prevent the automatic shutdown from working? When it does work, what would the user see? I am sure I am missing something about how the framework shuts down sessions.

Sure! If you’re upgrading your app, you’ll want to prevent further logins. If the app will still be actually running, you can simply call Session.Quit from within Session.Open if you want to.

It needs to be outside of the Session mechanism. You could send them to a URL under /api or /special and return an HTML page if you wanted to because those URLs do not spin up new Sessions.

No. The 3 minutes has to do with how long it has been since the browser last contacted the server. There is a mechanism in the javascript framework which periodically pings the server just to say “I’m still here, please don’t lock me out.” If the server doesn’t hear one of those requests for about 3 minutes, it assumes that the user has closed the browser window or tab which was connected to your app (or just gone to another URL) and will start the process of releasing the resources associated with that Session.

Circular references are the usual culprit (probably 95% of the time). If the Session’s Destructor can’t fire, it won’t get released from memory, nor will it attempt to release any of its properties.

The user has already left the app, so there is nothing to see. If the user returns after the Session has closed, they will be sent back to the default page.

That nails it. Thanks.

If I am using the Session.TimeOut and the App.HandleSpecialURL event to display a “Session Timed Out” page, do I need to use Session.Quit anywhere to close the session? I am guessing the answer is no but I am not certain about that. I know the special URL is not part of Session but is the Session still capable of pinging the server?

Also, is it possible to have an Exit button that just closes the current tab? The javascript window.close(); works in IE but not FF or Chrome. FF requires enabling dom.allow_scripts_to_close_windows. Chrome requires Kiosk mode. Any options? If not, should I just go to a special URL page that says “You have exited the app.”? I think it would be better to just close the tab but this isn’t allowed for security reasons.

Greg can this 3 minute period be accessed i.e. changed? the reason I ask is, a Xojo webapp on the iPhone with iOS 7 (don’t know about 8 )shuts down when the user switches to another app. i.e. like answering the phone. Safari is suspended.

It wouldn’t do you much good. JavaScript is all but stopped when your app is not the front most tab in iOS. I’m not 100% sure, but I don’t think there’s even an event that fires when it goes to the background, so we can’t even detect it.

Great reading!