Pushlets: Send events from servlets to DHTML client browsers

Discover how pushlets, a servlet-based notification mechanism, enables server-side Java objects to call back JavaScript code within a client browser.

These days, developers increasingly turn to servlets and JavaServer Pages (JSPs) as Web-based frontends that integrate backend databases, Enterprise JavaBeans, or legacy applications. It is, however, difficult to keep client Web browsers up-to-date when the state of backend application data changes after the client has loaded the HTML page. For example, how do you keep one user up-to-date when she views the contents of a database table in her browser while another user simultaneously updates that same table on the server?

Indeed, applications such as live stock feeds, flight-arrival information, or weather-condition updates, in which the server streams or pushes live data, are difficult to create with servlets or JSPs.

How can we ensure these applications will be capable of notifying the browser after HTML page loading? Or, how can we selectively update parts of a page, such as updating only the stock whose price has changed? As seasoned Java developers, we often reflexively think of applets that use sockets or RMI/CORBA as the only server-to-client notification solution.

In this article we'll look at a solution that may better serve our purpose. First, I describe the current solutions for server-to-Web client notification. Next, I introduce pushlets as an alternative -- and possibly unconventional -- notification mechanism and then present a simple pushlet framework with some sample applications. Finally, I discuss some of the advantages and disadvantages of applying pushlets.

Note: This article's examples and complete source code can be viewed and downloaded from http://www.fluidiom.com:8080

Server-to-Web client notification: Current solutions

Before we delve into the pushlet concept, let's review the existing server-to-Web client solutions. Assume we have a Java Web or application server from which we want to notify client browsers. Possible solutions can be categorized as HTML refresh, server-side callbacks, and messaging.

HTML refresh

The simplest notification solution is the HTML refresh. By using <meta> tags in the header of the HTML document, the page automatically reloads every n seconds. If something has changed on the server since the last reload, we get the new content; otherwise, we get the original page. The following simple line, placed between <head> and </head> in an HTML page, does the trick:

   <META HTTP-EQUIV="Refresh" CONTENT="4;URL=http://www.justobjects.nl">

While this solution is simple, we must still ask, how long should we make the refresh interval?

Server-side callbacks

In server-side callbacks, a server object calls back a Java-applet client using RMI (Remote Method Invocation) or CORBA (Common Object Request Broker Architecture). Usually the client first passes a remote reference of an RMI or CORBA object to the server. The server keeps a list of those references and calls them sequentially at the time of notification. This solution has been discussed in detail in other JavaWorld articles (see Resources).

Messaging

In messaging, an applet is a client of a messaging server that pushes messages over a TCP/IP connection (java.net.Socket) or sends connectionless UDP messages (java.net.DatagramSocket), the latter possibly even with multicast (java.net.MulticastSocket). You can use messaging middleware (MOMs), such as SoftWired's iBus, IBM's MQSeries, and BEA Systems' WebLogic Events, or develop your own custom messaging with java.io.ObjectStream on top of TCP or UDP sockets. The Java Messaging Service (JMS) is an important standard for messaging.

Each of the above solutions has its advantages and disadvantages in complexity, security, performance, scalability, browser Java compatibility, and restrictions such as firewalls. The optimal solution strongly depends on the requirements of your application. For example, when users require a direct interaction with the state, such as in a shared whiteboard, server-side callbacks or messaging can be a powerful technique.

But we are still working within the confines of a browser. Unless the applet constitutes the entire client application, it is difficult to integrate the HTML content with the updates coming from the server. Considering this, how can we alter the content from within the applet when it gets the callback or message? A frequent solution is to refresh the page by calling AppletContext.showDocument(URL) within the callback method. This instructs the browser to change the page with the new URL.

Enter pushlets

Since HTML is a powerful layout language, wouldn't it be nice to be able directly to alter parts of the HTML content with incremental data coming from the server? This would be an ideal scheme for Web applications where content on the server changes dynamically and the required user-to-server interaction -- for example, that driven by HTML forms.

The pushlet mechanism I developed is lightweight and thin on the client; it requires no applets or plug-ins, directly integrates with scripting and HTML, and uses standard HTTP connections; and it can be deployed (in theory!) in any Java-servlet server. It is certainly not meant to replace the traditional solutions outlined above. On the contrary, pushlets may be another option in your toolbox. As a Java architect or developer, you can determine the trade-offs and choose what is best for your particular application.

Pushlet basics

So what are a pushlet and how does it work? In its basic form a pushlet is extremely simple. I will show the basics through a few examples. It's also time to see some code!

HTTP streaming

Pushlets are based on HTTP streaming, a technique sometimes used in multimedia viewing applications such as QuickTime or RealAudio. Instead of closing the HTTP connection after fetching an HTML page, the connection remains open while fresh data is pushed to the client.

Taking the idea of HTTP streaming, we could develop a JSP or servlet that continuously sends new HTML content back to the client in a timer loop, as seen in the example below:

<HTML> <HEAD> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> </HEAD> <BODY BGCOLOR="blue" TEXT="white"> <% int i = 1;

try { while (true) { out.print("<h1>"+(i++)+"</h1>"); out.flush();

try { Thread.sleep(3000); } catch (InterruptedException e) { out.print("<h1>"+e+"</h1>"); } } } catch (Exception e) { out.print("<h1>"+e+"</h1>"); } %> </BODY> </HTML>

To see this example in action, from the Pushlets page, click on Examples, then Basics. Then click Run from the HTML Push section. The above example is not terribly useful, since the pushed content is continuously appended to the page while our intention was to alter the loaded content (that is, to show only the actual value of the counter).

In our next example, we jump right into the pushlet mechanics. Again from the Pushlets Examples-Basics page, click Run from the JavaScript Push section. Notice that the page refreshes every 3 seconds. How is that done?

The JavaScript Push example consists of three files: push-js-stream.html, push-js-stream-pusher.jsp, and push-js-stream-display.html. The main page, push-js-stream.html, contains each of the two other files in HTML frames. Let's just follow the route of the events.

When requested, push-js-stream-pusher.jsp, a JavaServer Page, executes on the server. The file's main body is listed below:

  7: <%
  8:   /** Start a line of JavaScript with a function call to parent frame. */
  9:   String jsFunPre = "<script language=JavaScript >parent.push('";
 10:
 11:   /** End the line of JavaScript */
 12:   String jsFunPost = "')</script> ";
 13:
 14:   int i = 1;
 15:   try {
 16:
 17:     // Every three seconds a line of JavaScript is pushed to the client
 18:     while (true) {
 19:
 20:        // Push a line of JavaScript to the client
 21:        out.print(jsFunPre+"Page "+(i++)+jsFunPost);
 22:        out.flush();
 23:
 24:        // Sleep three secs
 25:        try {
 26:             Thread.sleep(3000);
 27:        } catch (InterruptedException e) {
 28:             // Let client display exception
 29:             out.print(jsFunPre+"InterruptedException: "+e+jsFunPost);
 30:        }
 31:      }
 32:    } catch (Exception e) {
 33:             // Let client display exception
 34:             out.print(jsFunPre+"Exception: "+e+jsFunPost);
 35:    }
 36: %>

In line 21 above, we see a timer loop that prints HTML to the browser every 3 seconds. But wait, it's pushing JavaScript, not HTML! What does this mean? Effectively, it pushes a line such as <script language=JavaScript >parent.push('Page 4')</script>.

What does it mean for the browser? The browser, with its JavaScript engine running, obediently executes each line coming in. It calls the parent.push() JavaScript function. Now the parent is the parent of the frame it is in, which is the push-js-stream.html file:

<script LANGUAGE="JavaScript"> var pageStart="<HTML><HEAD></HEAD><BODY BGCOLOR=blue TEXT=white><H2>Server pushes: <P>"; var pageEnd="</H2></BODY></HTML>";

// Callback function with message from server. // This function is called from within the hidden JSP pushlet frame function push(content) {

// Refresh the display frame with the content received window.frames['displayFrame'].document.writeln(pageStart+content+pageEnd); window.frames['displayFrame'].document.close(); }

</script> </HEAD>

<FRAMESET BORDER=0 COLS="*,0"> <!-- frame to display the content pushed by the pushlet --> <FRAME SRC="push-js-stream-display.html" NAME="displayFrame" BORDER=0 SCROLLING=no>

<!-- Hidden frame with the pushlet that pushes lines of JavaScript--> <FRAME SRC="push-js-stream-pusher.jsp" NAME="pushletFrame" BORDER=0 SCROLLING=no> </FRAMESET>

The push() function called from within the JSP frame (pushletFrame) writes whatever it gets passed in its content argument into the displayFrame. The function push(content) illustrates some dynamic HTML: you can refresh the content of a frame or window by calling writeln of its document object. So the displayFrame is the real view where the content is displayed. It initially displays "Wait..." until the server pushes the first content.

<HTML>
<BODY BGCOLOR=black TEXT=white>
<H1>WAIT...</H1>
</BODY>
</HTML>

The example above demonstrates the whole idea of pushlets: we stream in lines of JavaScript from a servlet (or JSP in the example above) into a hidden frame. The browser executes the lines and may do something interesting. So effectively we have a callback from Java in the server to JavaScript in the client browser! Phew, that was easy!

The example above demonstrates the mechanics, but a couple of issues still have to be solved and features have to be added. For that reason I've built a simple event framework that supports pushlets -- but first I will pull you off the Java track with something called dynamic HTML.

Not just Java: Dynamic HTML

Long gone (in Internet time) are the days when a Website could be produced by the local sysop who scanned in some images from the company's brochure and knew a few HTML tags. The possibilities for manipulating content and user interaction within the browser are expanding through dynamic HTML (DHTML). As a Java programmer using servlets and JSPs, you should make DHTML part of your toolkit. Be aware that you will often have to make trade-offs when you divide functionality among the servlets or JSPs and the DHTML pages executed in the client browser. That is often not an easy decision, but knowing the advantages and disadvantages of DHTML will help you make a better one.

Dynamic HTML refers to a combination of HTML, Cascading Style Sheets (CSS), JavaScript, and the browser's Document Object Model (DOM). Traditionally, a page could be altered only by reloading a new page from the server. DHTML allows full control of an HTML document within a browser after the page has been loaded. You may have seen such examples as image rollovers, pop-up content, and collapsible menus. Most browsers at version 4.0 and later support DHTML, albeit with some differences in standards (see below).

From a programmer's point of view, the entire document in the browser -- its frames, images, paragraphs, tables, and so on -- is represented as a hierarchical object model, the DOM (not to be confused with the XML DOM). Through JavaScript you can manipulate the elements of the DOM and thereby change the content or appearance of the document. Moreover, you can capture user events such as mouse moves and form submissions, and subsequently process those events to modify DOM elements. For example, a mouse moving over an image may produce a mouseover event that, when processed, changes the image by popping up explanatory text. It sounds great, doesn't it? We just need to get familiar with the DHTML standard and off we go! Hmm, but who defines the DHTML standard?

That question hits an issue that has inhibited many developers from embracing DHTML. First, the browser must be version 4.0 or later. The official standards body for DHTML-related specifications is the World Wide Web Consortium (W3C). However, the Microsoft and Netscape browsers now each have proprietary DHTML extensions that you must track as well.

Luckily, the situation has become much better. Most users by now have the later browsers, and some people (in particular, the "Dannymen," Dan Steinman and Danny Goodman, see Resources) have done good work on cross-browser DHTML libraries that you can reuse. As a Java programmer, you may appreciate the fact that you can do reasonably clean object-based or even object-oriented programming in JavaScript. You will find examples in my basic DHTML demos (www.fluidiom.com:8080; choose Examples, then DHTML), but it is worthwhile to check the DHTML resources. Once you have browser issues hidden behind a facade of cross-browser libraries, DHTML programming becomes real fun.

So, with Java gaining more market presence on the server and with DHTML providing powerful features on the client, I decided to couple those two great technologies in a direct way, using pushlets. For that I implemented a lightweight framework for the server and some DHTML libraries for the client. These are discussed next.

A pushlet framework

The pushlet framework allows clients to subscribe to subjects within a server from which they subsequently receive events. The framework's basic design pattern -- Publish, Subscribe -- has both server and client components:

  1. A server-side collection of Java classes designed around the Publisher class and Subscriber interface (see Figure 1, a Unified Model Language, or UML, class diagram)
  2. A client-side reusable JavaScript library (pushlet.js) and HTML (pushlet.html) for receiving events within DHTML clients and passing them to the application
  3. Client-side Java classes (JavaPushletClient.java and JavaPushletClientListener.java) for receiving events within Java clients
  4. Cross-browser DHTML client utility libraries (layer.js, layer-grid.js, and layer-region.js) for displaying content in DHTML layers
  5. Generators for test events (EventGenerators.java) and example applications (www.fluidiom.com:8080; choose Pushlet, then Examples)

Server-side class design

On the server side, the key classes are the Pushlet servlet, the Publisher class, the Subscriber interface, and the Event class, as seen in Figure 1.

Figure 1. UML class diagram: Server-side pushlet framework

By invoking the Pushlet servlet through an HTTP request, clients subscribe to receive Events. The request indicates:

  1. For which subject they would like to receive Events
  2. In which format -- JavaScript calls (the default), XML, or Java-serialized objects -- Events should be sent
  3. Through which receiver protocol (currently HTTP only; additional protocols in future versions) they should be sent

A sample request for receiving Amsterdam Exchange (AEX) stock rates formatted as XML through an HTTP response stream would be:

http://www.fluidiom.com:8080/servlet/pushlet?subject="/stocks/aex"&format="XML"&protocol="HTTP-stream"

Subject identifiers are organized as a hierarchical topic tree. For example, /stocks identifies all Events related to stock rates, while /stocks/aex identifies stock rates for the Amsterdam Exchange. Likewise, the subject / indicates all events.

Currently, the only receiver protocol is a client HTTP response stream. In a future extension other receiver protocols such as TCP, UDP, RMI, HTTP POSTing, or even SMTP (email) will be able to be specified.

An Event is merely a set of name-value string pairs (implemented with java.util.Properties). The Publisher has an interface through which classes that generate Events can publish them. The Publisher keeps a list of Subscribers and sends each Event to those Subscribers whose subject matches the Event's subject. Events may be originating within the server through EventGenerators, which may listen to external events such as a stock feed. In addition, clients may publish Events through HTTP with the Postlet servlet. The responsibilities of other classes in Figure 1, PushletSubscriber and its contained classes, can best be explained through scenarios.

Figure 2 shows a UML sequence diagram for a client browser subscribing for Events from the Publisher.

Figure 2. UML sequence diagram: Client event subscription

Pushlet is invoked with the servlet doGet() method. Because multiple clients may invoke the same Pushlet object, it should itself not be a Subscriber. Instead, it delegates all subscription (and subsequent Event handling) by creating a new PushletSubscriber object for each doGet() and letting it run until finished with eventLoop(). The PushletSubscriber that implements the Subscriber interface registers for Events with the Publisher through the join() method. To deal with different client formats and protocols, it creates a specialized ClientAdapter object, in this case a BrowserPushletAdapter. For browsers supporting Multipart MIME, such as Netscape 4.0 or later, this would be a MultipartBrowserClientAdapter. The final call in this scenario is a "wait for event loop." Note that the deQueue() method suspends the execution of the current thread until an Event becomes available (indicated with a half arrow). This is explained through the next scenario in Figure 3.

Figure 3. UML sequence diagram: Event publishing and client notification

The scenario illustrated in Figure 3 shows how an EventGenerator creates an Event and calls Publisher.publish() to have it dispatched. The Publisher walks through its list of Subscribers and asks each whether the Event matches its subscription criteria (currently only the subject). If the Event matches, Publisher calls the send() method on the Subscriber. Each PushletSubscriber object has a GuardedQueue object in which it queues incoming Events when send() is called.

So why doesn't Publisher directly push the Event to the BrowserPushletAdapter? First, we want to suspend execution of the BrowserPushletAdapter thread until an Event becomes available; that is, we don't want to do a busy-wait (also known as polling). Second, a Publisher may notify multiple clients. Having a synchronous send() method call a slow client on the other end of the line may block all the other clients to be notified next. This is a design pitfall I also observed in RMI or CORBA callback examples in which a list of clients is called back synchronously -- client number 13 on a slow connection and a 386 processor may block the remaining callbacks.

The GuardedQueue, a utility object, uses the readers-writers pattern to enqueue or dequeue Objects, with guarded suspension using the java.lang.Object.wait() and notifyAll() methods. The thread of a client of GuardedQueue calling deQueue() is suspended (using wait()) until an Object is queued. Likewise, a client enqueuing an Object will be suspended as long as the queue is full. When the clients are fast enough, the GuardedQueue never fills up.

After the BrowserPushletSubscriber has dequeued an Event object, it calls the push() method on the BrowserPushletAdapter, which formats the Event to a JavaScript element and send it to the browser. For example, for a Royal Philips Electronics stock rate of 123.45, the JavaScript element would look like this:

<SCRIPT language=JavaScript >parent.push('subject', '/stocks/aex', 'philips', '123.45')</SCRIPT>

Now we have arrived at the client browser side. We assigned the Pushlet itself to a hidden HTML frame. Within this frame, parent.push() calls the push() function in its parent. This is effectively the callback that originated within the server. The parent frame has to implement the push() method. Since this is a common task for all browser clients, two reusable files for the client are provided: pushlet.html and pushlet.js.

pushlet.html is meant to be included in a frame within the application-specific client HTML document. It can be made a parameter with the subject identifier and a background color (such that it remains invisible). Most important, it implements the JavaScript push() method as follows:

function push() { // Create a PushletEvent object from the arguments passed in. // push.arguments is event data coming from the Server pushletEvent = new PushletEvent(push.arguments)

// Show blinking light as data is coming in updateStatusFrame();

// Is parent ready to receive events? if (!parent.onPush) { return; }

// Forward the event to the parent frame that should do // application-specific handling of the event parent.onPush(pushletEvent); }

The function push() first creates a JavaScript object from the parameters passed in. Yes, you can do object-based programming in JavaScript. Reminiscent of varargs in C/C++, JavaScript functions may have a variable number of arguments. A PushletEvent object is created with whatever arguments were passed to the push() method from the server. Let's take a look at PushletEvent implemented in pushlet.js:

/* Object to represent nl.justobjects.pushlet.Event in JavaScript. Arguments are an array where args[i] is name and args[i+1] is value. */ function PushletEvent(args) { // Member variable setup; the Map stores the N/V pairs this.map = new Map();

// Member function setup this.getSubject = PushletEventGetSubject this.put = PushletEventPut this.get = PushletEventGet this.toString = PushletEventToString this.toTable = PushletEventToTable

// Put the arguments' name/value pairs in the Map for (var i=0; i < args.length; i++) { this.put(args[i], args[++i] ); } }

// Get the subject attribute function PushletEventGetSubject() { return this.map.get('subject') }

// Get event attribute function PushletEventGet(name) { return this.map.get(name) }

// Put event attribute function PushletEventPut(name, value) { return this.map.put(name, value) }

function PushletEventToString() { return this.map.toString(); }

// Convert content to HTML TABLE function PushletEventToTable() { return this.map.toTable(); }

In turn, pushlet.js uses a Map JavaScript object, a java.util.Hashtable-like utility object.

Next, push() calls the updateStatusFrame() method to show a blinking light to indicate we are still receiving events. If a parent.onPush() function exists, push() calls that function with the PushletEvent. The parent.onPush() method is the application-specific, event-handling function that in this case may update the philips stock-related layer in a DHTML page.

That ends the description of the basic framework design. Now let's turn our attention to situations where we can apply pushlets and look at their strengths and weaknesses.

Pushlet applications

Pushlets allow many types of Web applications to be developed. Since the framework also allows for clients to upload events (through the Postlet), applications can do more than passively push data. Possible applications can be categorized according to:

  • Whether the events originate from the server, from clients, or both
  • Whether state is kept on the server, within the clients, or both

Moreover, since live events are made available to JavaScript, you can create scriptable plug-ins able to receive live updates. You may script your Macromedia Flash or VRML World application, for example.

Let's examine some possible applications.

Monitoring

With pushlets, various data sources -- stocks, weather, votes, flight arrivals, systems -- may be monitored live.

Gaming

Developers can create simple move-display games, such as a two-user tic-tac-toe and more elaborate chess, Risk, and Monopoly-like games. Players can make moves through postlets. An extended server could implement the game's logic and push changes in the game's state to the clients. In an upcoming version of the pushlet framework I plan to implement a generic multiuser session so that the players' presence and actions are communicated.

Distributed Model View Controller (MVC)

MVC refers to a design pattern often found in user-interface frameworks such as Java Swing and Microsoft MFC. In the distributed variant, a model (often the data) resides on a server, while clients hold the views and controls. The model is modified through the controls. The model then notifies all attached views, which subsequently refresh themselves.

Many applications may have a Web frontend through which data on the server is updated by multiple users -- flight reservation systems, for example. If one client makes an update, the others won't see it unless they continuously refresh their pages. In some cases that is a simple and workable solution, but in other cases users need to be synchronized with the update as it happens. That is easily done with pushlets pushing a URL as the single event. When a client receives the URL, it refreshes the page.

Enterprise JavaBeans (EJBs) server is an example. Although Java clients are able to talk directly to an EJB (through RMI or CORBA), more often servlets and JSPs are used as a frontend. In this case notification becomes much harder. With pushlets, an EJB could notify its attached Web clients whenever its state changes.

Web presentations

When referring to Web presentations, I once quipped, "Are you being surfed?" In fact, Web presentations, also known as Web tours, inspired me to develop pushlets. I abandoned PowerPoint in making Java course content and developed a content-management framework based on XML with slide presentations in HTML. Since classrooms frequently had no projector but all students had a networked computer, I developed a simple application (WebPres) that enable me to change HTML slides with all students automatically.

Web presentations can also be useful for call centers, banks, or help desks. For example, when I phone in with a question, a call-center agent may guide me to URLs with solutions, offers, or other information.

Community tools

Community tools include various applications where multiple users can join a live session. I originally had a prototype of the framework where I created a multiuser session as a collection of HTTP Session objects. I plan to extend the pushlet framework with such capabilities. For now, I have a simple Web chat and what I call WCQ (in Dutch this sounds almost like "We Seek You"), a simple ICQ-like desktop window where you can monitor the presence of friends. Other applications in this area include live forums and shared document editing.

The consequences of using pushlets

Like any other mechanism or design pattern, pushlets present obvious advantages and disadvantages when compared with Java-based applets that use messaging or RMI/CORBA client callbacks.

Advantages

  • Direct integration with DHTML within the browser: data generated by the server can be immediately integrated into the page content of the browser. Therefore, all the layout capabilities of DHTML can be directly applied. With RMI or CORBA it is difficult to integrate the applet with its containing Web page.
  • Standard HTTP port and protocols: messaging and RMI or CORBA use dedicated ports that may not work through firewalls, and browser security restrictions may prevent callbacks or data receipt over UDP.
  • Low client weight: Java applets with RMI/CORBA often make the client heavier in startup and resource consumption; pushlets don't.
  • No extra server: messaging and RMI/CORBA often require a dedicated server product or at least a registry running RMI. pushlets can, in theory, run on any servlet engine, using functions such as connection management and multithreading (which may be a disadvantage, as well, as seen below).
  • Small protocol overhead.

Disadvantages

  • Cross-browser DHTML: some effort is required to make cross-browser DHTML libraries that work in all browser versions on all platforms.
  • Scalability: when hundreds of clients connect through pushlets, they may hog resources such as threads and sockets. On this scale it would be better to serve pushlets off a dedicated servlet server optimized for this type of HTTP usage. However, scalability is also an issue with CORBA callbacks.
  • Web-server issues: a Web server is usually not designed for long-lived connections. One solution is the same as that applied above under Scalability. For large-scale applications, a pushlet applet client that receives notifications as UDP messages may be used. The HTTP request is then used only for subscription.
  • Proxy buffering: As one reviewer of the pushlet concept pointed out, some proxy servers may buffer HTTP data.
  • Quality of service: the server gets no direct confirmation that the event has been processed successfully.

Further work

I am further testing the viability of pushlets. The pushlet framework is a generic Publish-Subscribe pattern, with HTTP-based pushlet clients as a special case. I am developing the framework with the following extensions:

  • Additional client receiver-protocols such as TCP and UDP. One interesting possibility is calling an applet that receives UDP messages from within the pushlet frame on the client. That would mean we don't keep the HTTP connection. In general, clients will subscribe with a HTTP request on which they indicate through which protocol (TCP, UDP, RMI, HTTP-stream, or HTTP POST) they want to receive events and in which format (XML, Java-serialized objects, and so on). The address of the receiver is specified, where required. For example, to receive XML-formatted stock events through UDP on port 5001, the request would look like this:

    http://www.fluidiom.com:8080/servlet/pushlet?subject="/stocks/aex"&format="XML"&protocol="UDP"&port="5001"
    

    With UDP a lease time needs to be specified (since the server would never know when the client leaves). If the lease is not renewed within this time, the server will drop the client.

  • Additional client sender-protocols. Currently, events are generated internally or through the postlet by using the HTTP POST request. Additional protocols such as RMI, TCP, and UDP may be applied.

  • Subject state. Currently, a subject is just a hierarchical string. A client that subscribes gets no history that may have built up -- a chatroom discussion, for example. In a next version subjects become first-class objects, so that when clients subscribe they may implicitly get the current state or may explicitly request the state.
  • Multiuser. although some multiuser applications are possible, there is no multiuser session control on the server. In earlier versions I experimented with combining multiple HTTP sessions into a multiuser HTTP session.

Conclusions

In this article we have covered quite some ground: server-side Java, servlets, DHTML, design patterns, and a framework. In its essence the pushlet technology is very simple, and, given its advantages and disadvantages, it may serve as an alternative to RMI or CORBA for certain Web applications.

The pushlet framework is in its early stages and being evaluated by a number of users. You may visit the pushlet Website through http://www.justobjects.nl to see how development is progressing, to run examples, and to download the framework source. Since I have planned it as an open source project, you are welcome to participate in development and review.

Just van den Broecke of Just Objects (http://www.justobjects.nl) is a freelance architect, developer, and trainer specializing in object-oriented design, distributed Java, and Web technology. His Java projects range from banking applications to multiuser multimedia tools for performing artists (http://www.keyworx.org). He believes Java is most effectively applied when combined with other technologies such as dynamic HTML and XML.

Learn more about this topic

Join the discussion
Be the first to comment on this article. Our Commenting Policies