us site
developer center
search

Nexaweb’s IMB gets struck by a Comet

August 16th, 2008 by Bob Buffone

Just finished checking in the last of the updates (minus bug fixes) for the new Ajax IMB Client, after a week of straight coding and little else. The new version has been completely rewritten from the ground up. This coincides with Nexaweb’s upcoming release (in a month or so) of an updated version of the Ajax Client. The Ajax Client codebase will be completely updated and run over dojo 1.2. All the coding for these updates follow six principles:


  • Small
  • Flexible
  • Fast
  • Simple
  • Easy
  • Robust
  • Add Value

Applying these rules to the IMB code produced some great improvements in both size as well as functionality. Comparing the metrics between the old codebase and the new one shows considerable improvement.

  • Number of Classes - old 30 vs. New 10 - 67% savings.
  • Size - old 27KB vs. New 17KB - 37% savings. I had it down to 14KB before adding in the new features.
  • Complexity, if I were to measure it, would be 1/10 of the old codebase.

New Features:

The numbers tell only half the story. Developers will benefit from the simplified usage and increased functionality of the IMB codebase. Below are the features new to this version of the codebase:

  1. long-polling support - This is a huge benefit over the first version’s interval-based polling. Reading a lot about Comet techniques and looking through tons of code last week, I was able to get “long-polling,” as it’s known, into the codebase. WIkipedia has a good article on Comet as does Comet Daily. Opening the “push” connection is done as follows: imbSession.getSynchronizationService().openPushConnection();

    The great thing about long-polling is that it’s a very clean client-side implementation and works well in all the browsers. Most of the work for dealing with the complexity is done on the server-side. Our server already had all the infrastructure to handle long-polling and just needed some client-side love.
  2. Server Controlled - You can specify the synchronization mechanism for the IMB using a server configuration file; when the IMB is started, the server tells the IMB Client how it should configure its synchronization service: interval-polling (interval), long-polling or nothing. Again, the server was already sending the client the right information, I just needed to read it and configure the synchronization layer. In the WEB-INF/nexaweb-client.xml file you can configure the client to start a push connection (long-polling in Ajax) or start interval polling at startup.

    <default-session-configuration>
    <configuration>
    <polling-interval>2 seconds</polling-interval>
    <begin-polling-on-startup>false</begin-polling-on-startup>
    <establish-push-connection-on-startup>
    true
    </establish-push-connection-on-startup>
    </configuration>
    </default-session-configuration>

    The configuration can be customized for more advanced behavior such as starting a push connection for IE and a ten-minute polling interval for all other browsers.
  3. Events - Developers can now manage all common events that occur in the Ajax client. This allows developers to handle session time outs, polling errors, and more.

    dojo.connect(myIMBSession, "onSessionTimeOut", displayRestartDialog);
  4. Policy based management of the transport: Nexaweb’s server infrastructure has always been a very well thought out piece of code. Developers or Administrators can control every aspect of the IMB to get just the right balance of performance and client throughput. The WEB-INF/nexaweb-client.xml file can configure how data is sent up the push connection. Originally intended to more effectively manage complex network topologies, the IMB policies allow the configuration of data pushes to the client. The following piece of XML from the nexaweb-client.xml demonstrates this capability:

    <policy>
    <configuration class="com.nexaweb.server.pushconnection.
    flushpolicies.ThroughputFlushPolicy">
    <flush-size>1 bytes</flush-size>
    <is-stream-closed-on-flush>true</is-stream-closed-on-flush>
    <measurement-period>2 seconds</measurement-period>
    <minimum-throughput>500 bytes</minimum-throughput>
    </configuration>
    </policy>

    This tells the server to use the throughput policy, whereby data being sent up the push connection waits either 2 seconds or until the payload is 500 bytes before it’s sent to the client. Why would this be a good configuration? Maybe you know that data comes in very short bursts and want to wait until the end of the burst before sending the data. Setting the policy to 1 millis and 1 bytes would mean that the server would send the data and cut the connection for every message. Although this might send the data quicker initially, the data would be choppier. Also more resource requests would be made resulting in poor performance and higher resource consumption.
  5. Robust error handling: One thing we are trying do throughout the codebase is to introduce better error handling to warn developers about issues or things that they should not do, and prevent them from happening. Below are some examples of this in the IMB code.
    • Developers can no longer start up two polling tasks
    • Can’t subscribe to a topic with the same handler twice
    • The codebase notifies developers if the session is invalid when they try to use any of the services…

Existing Features:

The IMB already had some cool features in it, which have now been recoded following the rules above to hopefully make them easier and more robust.

  • Automatic request proxying: Say a developer wants to load an RSS file from digg.com - they can use the following code to do so:

    session.getRequestService().retrieve("http://digg.com/rss/index.xml");
    session.getRequestService().retrieveAsynchronously(
    "http://digg.com/rss/index.xml", {
    requestCompleted: function(request, response){
    },
    requestFailed: function(request, response){
    }
    });

    The IMB will detect this is as a cross-site request and proxy it via the server. This means that the client never needs to open up cross-site requests and developers can manage it from the server-side.
  • Simple Resource retrieval: The IMB “RequestService” can be used to access server-side resources with either a synchronous or asynchronous connection. The API is the same as shown above, but if the resource is within the application, the IMB retrieves the resource as any other Ajax framework would.
  • Automatic Resource Processing: dojo.E and the Nexaweb platform allow developers to use Xmodify syntax to change the HTML DOM or dojo Widgets. Using the following methods, developers can simplify this by telling the IMB to automatically process the results of the request:

    session.getRequestService().retrieveAndProcess("login.jsp");
    session.getRequestService().retrieveAndProcessAsynchronously("login.jsp", {
    requestCompleted: function(request, response){
    },
    requestFailed: function(request, response){
    }
    });
  • Pub/Sub is the metaphor for how the IMB handles its real-time messaging. Any “node” (Client or Server) within the application can subscribe to a topic and no matter where the message is published from, all subscribers receive a copy of it.

    session.getMessagingService().subscribe("chat-with-me", {
    onMessage: function(topic, message){
    var div = dojo.byId("last_"+topic);
    div.innerHTML = message;
    }
    });

    New to this version, developers can supply a function to be called when a message is received for a topic.

    session.getMessagingService().subscribe("chat-with-me",
    function(topic, message){
    });
  • Clustering: The IMB is fully clusterable, which gives applications unlimited scalability. The clustering has been in production deployments for fours years now and proven in large scale deployments such as Tokyo-Mitsubishi UFJ. Clustering the IMB is necessary for mission critical applications like MUFJ’s FOREX Trading Platform. When dealing with millions of dollars, messages must be delivered no matter the circumstance. Clustering removes any single point of failure in the back end, allowing machines to crash or be taken off-line without interruption to the service.

Sample Applications:

I have created two sample applications that demonstrate the functionality of the improved IMB.

  • Tic-Tac-Toe - A simple, single player Tic-Tac-Toe game with the Artificial Intelligence (it’s all relative) embedded into the server. When the user moves or sends a message, the server initiates the AI to respond to the messages and moves by publishing a response message.

  • IMB Dashboard - This application allows users to control every facet of the IMB functionality through a simple to use UI. To see what the new push connection does, open up two browsers and have them talk to each other by subscribing to the same topic.

That’s It:

Can’t think of anything else to mention about the new or old IMB code so I’ll end it here. Oh wait, one last thing, a sample application. Been trying to think of a cool app, something simple yet useful or at least fun for a couple minutes, but haven’t settled on one. I will create the super awesome chat application but want something a little more engaging. Any ideas, add them via the comments.

Bob (Buffone)

Tags: , , , , , ,

Leave a Reply