The Server Labs Blog Rotating Header Image

HTML5 Websocket vs Flex Messaging

Nearly 18 months ago, I wrote an article on this blog which showed how to develop a simple flex web application using ActiveMQ as a JMS server. It has proved a popular article so there must be a fair amount of interest in this topic.

With all the hype surrounding HTML5 at the moment, I figured I’d try to update the application for the HTML5 world, at the same time seeing how easy it would be to replace Adobe Flex. I’m sure you’re all familiar with the fact that Steve Jobs won’t let Flash (and therefore Flex) onto either the iPhone or iPad, so it’s worth investigating if the alternatives (in this case HTML5 websocket) are really up to scratch.

The example shown in the article uses HTML 5 websocket, Apache ActiveMQ, the Stomp messaging protocol and (indirectly) Jetty 7. It currently only runs in Google Chrome 5 since this is the only browser with support for websocket available as of May 2010.

What is Websocket?

In short, it’s a way of opening up a firewall-friendly bi-directional communications channel with a server. The channel stays open for a long period of time, allowing the server and client web browser to interchange messages without having to do polling which consumes bandwidth and a lot of server resources.

This article describes websocket in much more depth.

Websocket forms part of the (still unapproved) HTML5 specification which all browsers will eventually have to implement.

Updating the Trader app

In order to get the best out of this section, it is probably best to have read the original Flex-JMS article.

Here is the code for the updated trader app. Instead of having a server webapp component with BlazeDS acting as a message proxy and the flex clients, we have a bunch of HTML/CSS/JS files (in the /html folder) and some code to put messages in the JMS queues published by Apache ActiveMQ (in the /server folder).

Setting up Apache ActiveMQ

Apache ActiveMQ now comes with support for Websocket (implemented behind the scenes with Jetty 7). We will use ActiveMQ both as our messaging server and web server in this example, though that is not perhaps the best production configuration.

This article explains how to configure ActiveMQ and Websocket. I will repeat the key instructions here for the sake of simplicity:

  1. Download the latest snapshot of Apache ActiveMQ 5.4 from here and unzip it somewhere on your filesystem that we will call $ACTIVEMQ_HOME
  2. Edit $ACTIVEMQ_HOME/conf/activemq.xml and change the transportConnectors section so that it looks like the example below:
            
                
                
                 
                 
            
    
  3. Start ActiveMQ by running bin/activemq from the $ACTIVEMQ_HOME directory. Go to http://localhost:8161/admin/ and log in with the username/password admin/admin to check that everything is working ok.

Configure an install the aplication

Download the trader app code and copy the /html folder to $ACTIVEMQ_HOME/webapps/demo, renaming it to /trader-app-websocket (i.e. the full path should be $ACTIVEMQ_HOME/webapps/demo/trader-app-websocket).

Edit stock-quote.js and note the following section:

    var url = 'ws://localhost:61614/stomp';
    var login = 'guest';
    var passcode = 'guest';
    destination = '/topic/stockQuoteTopic';

The url attribute referes to the URL of the ActiveMQ server. Due to a bug in Chrome running on Ubuntu 9.10, I had to put the IP address of my machine here but if you’re running on another linux flavour, OSX or windows, I would imagine that leaving it as localhost should be OK. The username and password are guest/guest which is standard for ActiveMQ.

Download the latest version of Google Chrome (I have 5.0.375.55 which was released a few days ago) and open the URL http://localhost:8161/demo/trader-app-websocket/. You should see a UI that is similar to the Flex app developed in the original article:

chrome-initial

Open up a terminal window and go to the location to which you extracted the /server part of the code download. Run the following (assumes Maven installed);

mvn clean compile exec:java -Dexec.mainClass="com.theserverlabs.flex.trader.JSONFeed"

You should see a whole bunch of stock quote information like that shown below scrolling in the terminal:

{"symbol": "XOM",
"name": "Exxon Mobile Corp",
"low": 61.317410451219146,
"high": 61.56,
"open": 61.56,
"last": 61.317410451219146,
"change": 61.317410451219146}

This Java program is the same as that used in the original post. It generates random stock price information for a variety of stocks and publishes it in the stockQuote topic in ActiveMQ. In this case, it generates JMS text messages which contain data formatted in the JSON format.

If you go back to the Chrome browser window, you should see the stock quotes update. If they don’t update, click on refresh:

chrome-stocks

This is pretty much exactly the same as how the original Flex application worked. The UI colours etc. are slightly different and I’ve not implemented the functionality for subscribing/unsubscribing from a stock price – but that was just on time grounds, not because it is difficult.

How does it work?

When the browser opens the page, it executes the following code in stock-quote.js, which subscribes to the stock quote service:

$(document).ready(function(){

    var client, destination;
    
    ... 
    
    var url = 'ws://localhost:61614/stomp';
    var login = 'guest';
    var passcode = 'guest';
    destination = '/topic/stockQuoteTopic';

    client = Stomp.client(url);
    client.connect(login, passcode, onconnect);
 
});

Here we use the library provided by Jeff Mesnil which enables us to access ActiveMQ using the Stomp protocol instead of JMS. We use it here because it is simple and cross-platform. There is no way of directly subscribing from JavaScript to a JMS server via JMS because there is no client available.

In the same block of code, you can see the code that we execute when we receive a message:


    var onconnect = function(frame) {
      
      client.subscribe(destination, function(message) {
        var quote = JSON.parse(message.body);
        $('.' + quote.symbol).replaceWith("" + 
            "" + quote.symbol + "" +  
            "" + quote.open.toFixed(2) + "" + 
            "" + quote.last.toFixed(2) + "" + 
            "" + quote.change.toFixed(2) + "" + 
            "" + quote.high.toFixed(2) + "" + 
            "" + quote.low.toFixed(2) + "" +  
            "");
      });
    };

When we receive a message, we parse it using the JSON parser that is part of the JQuery library and then we find the HTML element with class attribute equal to the symbol (e.g. if the symbol is IBM, we look for the HTML element with class=”IBM”) and replace it’s contents with the HTML table row code generated in the method. Simple really.

The rest of the code is just HTML and CSS and is not really that interesting for this article.

Conclusions

It is pretty easy to develop an application that uses Websocket – you only have to look at how little real code there is in this example. I’d say it is as easy as developing the original Flex app so from a development point of view, there’s little to chose between these technologies.

Unfortunately the only browser that currently supports Websocket is Google Chrome (and the implementation is a bit buggy). Other browsers (especially Firefox and Safari) should have this functionality soon though. One of the arguments used in support of Flash/Flex has always been the large installed base. Given that the iPhone and iPad are not part of this installed base, it is questionable as to whether this can still be used as a justification for using Flash/Flex. Sure there aren’t that many browsers that support Websocket but in 6 months time they probably all will and you won’t need any proprietary plugin to access the apps build using them. I’d definitely recommend that people developing internal corporate apps who can force their end users to use a browser with Websocket support take a look at this technology. People developing publically accessible webapps are probably going to have to wait till it is more widely implemented in browsers and provide graceful fallback in the case in which it isn’t.

I should point out that I have an iPhone and use Ubuntu 9.10 64-bit at work and I hate not being able to see content on my iPhone because it has been implemented in Flash and my entire firefox browser often crashes completely due to the 64-bit linux Flash plugin.

I’ve gone from being a fan of Flash/Flex to not being so sure about it. It’s hard to escape the feeling that HTML5 will offer much of the functionality currently offered by Flash/Flex in a short period of time. I think the future of these technologies is going to depend on Adobe innovating and offering stuff that is not possible in HTML5, otherwise there is little reason to use it.

9 Comments

  1. Guy Mac says:

    I’m sure you know that Safari 5 out now has websocket support….

  2. Kevin McCormack says:

    Yeah, I had meant to update the post to reflect the fact that Safari 5 had Websocket support but you’ve saved me the trouble!

    Cheers,

    Kevin.

  3. jpvincent says:

    so, now you tried both, do you think that a JS wrapper that will use the WebSocket when available and fall back to use a piece of Flash with Flex Messenging is doable ?

  4. Kevin McCormack says:

    @jpvincent

    I’ve not tried this but the jwebsocket project indicate that they have a JavaScript library that first tries WebSocket and if the browser doesn’t support it, falls back onto ‘jwsFlashBridge’, something that appears to rely on Flash being installed in the browser. I’d imagine it routes the comunication via a small embedded Flash app called via JavaScript instead of using the native browser sockets.

    Like I say in the article, I see this as mostly useful in scenarios where you can force the user to use a certain browser with Websocket support (e.g. internal corporate apps) at the moment.

    Hope this helps.

  5. Hi Kevin,
    Just came across this article. good stuff!
    To add to your reply to jpvincent, Kaazing has a WebSocket Stomp implementation as well (a complete JavaScript library).
    The Kaazing WebSocket Gateway also provides a full emulation of WebSocket for older browsers (without the need for Flash).
    Flash emulation for secure WebSocket usually requires you to open a separate port on your firewall (for the policy file), which sort of defeats the purpose 😉
    –Peter

  6. Philip Arad says:

    Hi

    I have followed exactly your instructions, to activate the WebSocket for Google, but nothing is passed back to the browser…
    How can I debug it ?

    Regards
    Philip

  7. Philip Arad says:

    After some investigation, it is working:
    1.I have upgraded: jetty-all-server-7.0.1.v20091125.jar and jetty-websocket-7.0.1.v20091125.jar to jetty-all-server-7.1.6.v20100715.jar and jetty-websocket-7.1.6.v20100715.jar
    2.I have changed the name of the topic:
    On the client: ‘/topic/test.topic’
    On the server: “test.topic”

    Thanks for your article.

    Regards
    Philip Arad – Web Architect at SolarEdge

  8. […] HTML5 Websocket vs Flex Messaging – The Server Labs Blog HTML5 Websocket vs Flex MessagingJun 9th, 2010by Kevin McCormack. […]

  9. I have checked it and it’s working. Thank you. Kevin.

    Richard
    Flex Developer

Leave a Reply