Wednesday, February 23, 2011

HTML5 WebSockets Adventure

I just recently spent a few days exploring the jungle that is WebSocket support in browsers and servers and I lived to tell about it. I say that it is a jungle because it is obvious to me that with the specification (IETF) not yet finalized this technology is still on the "bleeding edge".

I think it is important to note my particular frame of reference, my world view...I normally do not wish to pull the sources, build my own binary, hack on the default app server jar files, etc. My preference is to find a solution, download a binary version, install/unzip, run and load an out-of-the-box example. In addition, I am looking for a Java-based server, one I can extend with my own custom Java components - ideally a Java EE Servlet container.

My WebSockets Use Case
Thinking like the average Java web developer, I wish extend pieces of my server-side enterprise infrastructure out to the client browser application. One of the reasons that I am excited about HTML5 is that feels like client-server development of the mid-90s - back in the dark ages of PowerBuilder and Delphi. :-) Today, you primarily have to use Adobe Flash Flex for those ultra-rich, real-time capable browser-based UIs but that could change with HTML5. Note: I do not consider Silverlight nor JavaFX to be a real competitor to Flash-based applications at this time.

So, I want to build "dashboards", in jQuery, where the client-side browser is pushed data in real-time. Where my server-side Java architecture is likely a distributed fabric/grid or messaging and where particular data of interest can flow easily to my end-users just as it does around the average datacenter. OK, that might not be the average web app use case, but it is the one I am most interested in.


Step 1: Find a Browser

First thing to point out is that I am not one of the cool kids - I am still running Windows (v7 64-bit). I haven't joined the rush of hardcore techies who are sporting sexy MacBook Pros or big iron Linux workstations.
* Chrome 9.0.597.98 - supports WebSockets out of the box
* Safari 5.0.3 (7533.19.4) - supports WebSockets out of the box
* Opera 11.01 build 1190 - needs to be enabled by end-user
http://my.opera.com/ODIN/blog/2010/12/17/new-html5-features-in-opera-11
* Firefox 4.0b11 - needs to be enabled by end-user
https://developer.mozilla.org/en/WebSockets
* iOS 4.2.1 (8C148) on my iPhone 3G (wifi only supported, killed AT&T service plan)
* Android 2.2 on my Motorola DroidX - no - I also looked at Opera Mobile for the Android but that did not seem to support WebSockets

Testing browsers for WebSockets support
http://websocket.org/echo.html
http://jimbergman.net/websocket-web-browser-test/ - however, this one malfunctioned with my FireFox4

Step 2: Learn

Learn enough to be dangerous, never enough to be great. I am just getting started with a new capability and only had a couple of days to invest so far - needed to get moving as fast as possible. How does every technology explorer get moving these days? Google. Not only is Google your secret weapon for trivia night at the local pizza joint/bar, it can become your lifeline. I found many examples and several of those are now outdated, they just do not work. A few examples are provided by Aditya Yadav for the book Deploying HTML5. One using Netty and another using Jetty - I could not get either one to work - could be user error or could be they are based on the older version of the spec.

One thing that I noticed that demonstrates the relative immaturity of this space, when things do fail, you often do not receive error messages on the servers, nor in the browsers. If you are using a browser-based debugger (e.g. Firebug, Dragonfly), at least you will receive JavaScript error messages, but nothing specific to WebSockets malfunction. In the vast majority of my tests there was only silent (but deadly) failure.

Step 3: Find a Server
My "short-list" of solutions to explore included:
Kaazing
Resin
Jetty
Atmosphere (with JBoss, Spade, Tomcat and Jetty)
Infinispan

Kaazing
Obviously a commercial product with a professional grade website, cited in the html5rocks.com presentation for WebSockets and hosts a really cool online demo at Kaazing.me.

Download, installation, running example in mere moments, it just works. I did not spend more time on Kaazing because I am looking for something that is more Java EE server like.

Resin by Caucho
The Resin team provides a nice write-up on WebSockets at caucho.com/resin-4.0/examples/websocket-java/index.xtp
This particular tutorial broke down for me when I noticed that the client portion of the example was written in PHP. I just do not have the patience to translate the PHP into JSP - call me lazy.

Jetty by Webtide
While Jetty is very popular amongst Java developers who use it as a solution for localhost automated testing (JUnit, TestNG, Selenium, etc), it is not a server that I have spent a lot of time on. The Jetty world is a bit confusing on its own - there are many, many versions, from multiple download sites and multiple Eclipse plug-ins. Just google for "Jetty Download" or "Jetty Eclipse plugin" and you will see what I mean. It can take you several attempts to find the right combination to get everything working.

Then, if you google for "Jetty WebSockets" you end up with a lot of results, but no tutorial, no documented "getting started" that I could find.

Atmosphere
Atmosphere is not specifically a server, it is an open source library/framework that can be added to your favorite Java server (e.g. Tomcat, JBoss, etc). Atmosphere is where I spent the largest portion of my exploratory time - I really wanted to make this one work. It has many examples, including pub-sub with jQuery, my specific area of interest. This one certainly looked the most promising before I dove in.

Atmosphere + JBoss 6
I started with this combination because I get a paycheck from Red Hat so it tends to be my favorite Java application server. Well, that turned into a few hours of hacking away for no positive results. There was someone who wrote up his notes in the Atmosphere Users List but I was unable to follow the same path to make it work.

Atmosphere + Tomcat
I also failed to make Tomcat 6 and Atmosphere work together. Some of the setup/errors are identical to JBoss (it embeds Tomcat) like getting the right version of tc-native1.dll but I was weary after the JBoss attempt and didn't really push hard on Tomcat.

Atmosphere's Spade Server
After a few hours of frustration, I then realized that Atmosphere has an "out-of-the-box" ready to go server so I assumed THAT had to be the answer - downloaded, unzipped, started, fail! The startup looks like
java -jar atmosphere-spade-server-0.6.5.jar -a atmosphere-websocket-chat-0.6.5.war
As I said earlier in the post, you often get no error messages and this was a specific example that I remember. It even loads the page into your browser but nothing happens, clicking the buttons does not work.

At this point, I realized that I was going to need some help - Google, reviewing blog posts and digging through email list archives via Nabble was simply not getting me anywhere. So I jumped on the IRC channel and found jfarcand, the fellow who basically answers all the questions on the email list and blogs for Atmosphere. He was very kind and helpful, my basic question was...is there a setup that is just known to work? answer: Atmosphere + Jetty

Atmosphere + Jetty
Wow, it just works. After several hours of beating my head against the proverbial wall with standalone Resin, standalone Jetty and other Atmosphere combinations this was an amazingly blissful moment. I was able to get the atmosphere-websocket-chat-0.6.5.war to work immediately. And I was also able to figure out what combination of Jetty's WTP plug-in and server played nicely with each other - so I have this little demo editable inside of Eclipse Helios with drag & drop deployment to Jetty.

Infinispan
Infinispan was actually the first place I started when I begin this journey. There is a nice write-up/tutorial on using WebSockets with Infinispan and an example that ships with the distribution. Unfortunately, like almost all of my attempts, version 4.2.0.Final fails "out-of-the-box" with current browsers. The good news is that Galder Z was able to dig in immediately, figure out the specific problem and get it fixed - I have tested his patch and things look very good for 4.2.1.Final.

Conclusion
I had originally thought I could have my own custom application built using WebSockets with the weekend + two business days I had budgeted for the effort. Alas, I was only able to get some out-the-box-examples working with Atmosphere + Jetty and with Infinispan + patch. With that said, I am still very excited about the next generation of web development using the new features that fall under the HTML5 umbrella. The best part about being in the IT business is the constant change - tough to get bored - but that is obviously a double-edged sword. :-)