Session expiration issue in Web 2.0 applications
Traditional web applications consists of thin html based client that makes request to a thick server for most of its user activities. Thick server or application servers will typically associate a "session object" for each of its client. These session-objects will have a "time out" window that keeps track of user inactivity. If the user is inactive for certain time interval, (s)he should be logged off from the system and server resources should be reclaimed. Servers typically have background threads that keep track of inactive sessions and flush them off as and when timeouts happen. This works great on the server side. However, session termination message is passed on to the client browser only when a new request is made after the time-out interval is elapsed.
This approach might not always work in case of web2.0 or ajax or thick client based applications where lot of data/processing exists on the client. Client might continue to work on locally loaded data without making a server call even after the time out interval. Example: user modifies form fields or type in lot of text in an textarea while session time out has already happened on the server. User might end up loosing all the information when he actually hits the save button. Even worse is the security scenario: A user might have left his computer unattended, machine unlocked and browser window open with the web application running in it. Server might have logged off the user and cleared his session information, but some(pre loaded) data is still visible/available in his browser window. Ideally all this data should had been cleared the moment session time out happened.
The big issue here is http protocol's stateless nature. Sessions are tracked between a browser and the server with an internal token exchange mechanism. This token or session id is not part of the http protocol. Http by its very nature will only transport packages(request/response) from source to destination. With that said, servers cannot communicate with browsers at will. If that was possible, we could have send a session time out message to the browser as and when it occurred. Unfortunately there is no standard protocol between browser/server to achieve this.
Sending messages from the server to client is called "server push". In web2.0 world it is also called "reverse ajax". There are different ways to achieve this:
Client polling: Client(browser application) pings the server every pre determined interval to see if server has any data/message that needs to be pushed. Orbitz, Priceline, etc use this mechanism for there long running search queries . Unfortunately this will not work in our scenario where we need to communicate session time out information. Every time the client hits server, session gets renewed!
Piggyback: In this technique, server piggy back or append its message/data(if available) with every request that is received from the client. This method is better than client polling in terms of performance or bandwidth utilization. However it has same problem for our session timeout issue. Moreover piggyback mechanism cannot be used for instant/immediate server push. Server has to wait for that next client request in order to pass an message or event information.
Comet or Comet like: Comet is actually an umbrella term for techniques that work on long running transactions between the client browser and server. Idea is simple: Browser sends a request; server never returns a response; instead it keeps the connection open by sending KEEP-ALIVE messages; whenever the server wish to communicate data/message, it utilizes this open channel. This method works for our scenario, this is how we handle the session time outs:
- When the user logs in for the very first time, browser sends a request to the server which is never responded. Only KEEP-ALIVE flags are send back to browser. To do this, you will require 1 Server thread per user session that will sleep until time out happens. To receive session time out event, this thread will have to register a session time out listener/handler with the server.
- You might want to inform the user about inactivity and give him a change to save his session. To do this, you need to create a custom session time out job that will trigger a time out event just before the actual time out. Actual time out parameter value can be read from the session itself. When the custom time out job event happens, you should compare inactivity time with job's activity period. If the comparison result is false, some activity happened since the job was last scheduled. Job should be rescheduled with new timeout interval. If the comparison result is true, no activity has happened for the job time frame. You should now alert the user with a message(You will be logged off in x seconds, click Continue to save your session) and Continue button. If user hits the continue button, a server call should be made and job should be rescheduled with new session time out interval. If the user fails to hit continue in x seconds, you should log him/her off automatically and also display a user friendly message, informing him/her of the timeout event. You will have to create a client side timer for the exact(excluding the n.w. latency time) delta time for which his session will be active at time of displaying the very first message.
- This approach works like charm if implemented properly. However there are some issues. Browsers typically spawn maximum 2 concurrent request threads per server session. By blocking one request on the server, browser has only one more request thread in its hand for communication. This means, two images cannot be downloaded at the same time; t files cannot be uploaded at the same time; etc. Browser will synchronize all the events.
- Another issue: On the server you will require extra resources to handle this form of communication. You will require at least 1 thread and scheduled job per active user session.
It needs mention that webservices which operate over the same http channel already have this concept in form of "WS Callbacks". I am positive that server push or reverse ajax or server callbacks will be standardized and incorporated by the browser/server providers in near future. Till then, we will keep discovering new solutions!
Labels: reverse ajax, server push, session timeout