6/19/2007

Conversation State on the Client using Applets

The Problem
Web applications often require a large amount of data to be stored to maintain the session state of the clients, spanning multiple requests. There are multiple options to store session state, including hidden form fields, cookies, the web layer (the HTTPSession), the EJB layer (rarely, if you are a fan of stateful session beans), and finally the database. (The last thing you want to do is use your database as a "scratch pad" for each client!) Experience says that storing state information at the database or EJB layer has limitations and performance concerns.

For a browser-based web application, whose architecture is realized through a servlet on the server side, it is typical that we store the client's session state at the server end. This means that we dump the aggregation of the data of all clients into HTTP sessions. As a result, our architectures have inherently given way to overloaded servers that spend more of their energy and potential in maintaining clients' HTTP session state rather than actually serving requests. Yes, we do have the option of scaling the servers to meet the concurrency needs beyond these constraints through clustering or other methods. However, the fact remains that the much of the effort spent by servers in maintaining HTTP state information for each client (in terms of space complexity) is very high compared to the actual servicing of the client requests.

Let's plug in values to see the order of magnitude. Suppose that for a typical web application, an application server stores 300K of data per client HTTP session and is expected to serve 1000 concurrent users. Straight away, 300MB of memory is eaten up by the server's function of maintaining clients' HTTP session states, leaving the rest for actual request processing.

The real problem, the reason that the server is made to store all the HTTP session states of the clients, is that the HTTP protocol is stateless. That means that between two requests, a client communicating through HTTP to a server will lose track of the data stored in the current session or conversation. So, we decided to dump states of all clients on the server. That is exactly the point. Now, let us see an alternative to work around this problem.

A New Approach
Here, I propose an applet-based approach to persist HTTP state information on the client end that can replace some of the techniques discussed above. The idea is to distribute an applet to each client on the first HTTP request. This applet would be persisted as long as the conversation with the server, or according to the business logic. Each client's state information will be tracked using the applet at its own end. Between multiple pages of navigation, the applet would serve as a "session tracker." The applet will be disposed when the conversation is over with the server according to the business logic (for example, the checkout option on an e-shopping site) or when the user closes the browser.

To visualize how it would work for an e-shopping application, we will look at a simple e-book shop that sells different types of books. The application consists of multiple web pages containing books classified just as they are on Amazon.com. As the user navigates the pages in the website, he can keep adding books that he intends to buy to his "shopping cart."

In the traditional method of storing client session state in the server's HTTP session, the browser would post HTTP requests to the server and the server would maintain the shopping cart. Instead, what we are going to do is to update the session state stored in the applet residing the client side. One plus is that we don't communicate over the network here to update session state. Another advantage is that the server is going to bother about a client only when it actually requires server-side processing and validation, not when the user does trivial actions like deleting or modifying his shopping cart.

On login, the server would send back an applet to the user, which acts as the shopping cart for the user throughout the current session. One way to do this is to embed an applet tag in the returned HTML/JSP page, so that the applet is loaded and initialized in the client's browser. This effectively bootstraps the applet as the shopping cart for the user.

Each time the user modifies his shopping cart by adding or removing books or changing the quantity of books purchased, a JavaScript would be invoked, which in turn delegates the call to the applet. But how? The concept here is that when we embedded the applet inside the returned web page, we made it a part of the Document instance in the browser, as per the DOM specification. For a more details on how JavaScript can communicate with an applet, see the Resources section.

Remember, to use the applet as a session tracker, the session state data need to be persisted across pages until the user decides to check out. But we have a problem: when the user clicks to move on to another page, the browser simply moves the existing Document instance to History and creates a new Document. Consequently, our applet--part of the Document--along with the session state data is lost. To overcome this problem, we use a simple yet interesting characteristic of applets:


Limitations
Of course, this approach has all the limitations that any applet-based client has. Applet-flavored user interfaces require a basic Java runtime at the client side. Especially when the application is accessed over the internet, this means that some users need to download and install Java plugins for their browsers. It is easier, however to do that across all user desktops if the application runs within a managed intranet.

Another effect of this approach is that the client machine needs adequate memory to store session data. Since we are deploying our applet as the delegate at the client side to store session state, any memory leaks could crash the user's browser or JVM. To avoid this, memory requirements need to be analyzed and taken care during development.

However, if you are wondering if security is a limitation, think again: our session tracker would be loaded on the AppletClassloader which has strict but customizable security features.

Source : www.java.net

No comments:

Tired of seeing that 500 Bad gateway error while deploying a Springboot application in AWS...?

By default, Spring Boot applications will listen on port 8080. Elastic Beanstalk assumes that the application will listen on port 5000. Th...