wesleyhales.com

Pushing CDI Events to the Browser with WebSockets

20 January 2012

html5 | websocket | jboss | jetty | cdi |

Disclaimer: Minimal load testing was performed with 10000 concurrent WebSocket connections. You can see some true performance numbers here.
Github Icon Download

Here is the demo in action. As you can see on the right, I have 2 chat windows open and on the left we have a member registration. Users are chatting across a raw WebSocket connection and when another user registers, the CDI event is fired all the way through to the browser as a JavaScript alert via the connected WebSocket clients.

With WebSockets, we have a new development model for server side applications; event based programming. There are 3 out-of-box events associated with WebSockets: onopen, onmessage, and onclose. For starters, we must wire up these three listeners to utilize the core functionality that the WebSocket specification gives us. The open event is fired when the WebSocket connection is opened successfully. The message event is fired when the server sends data. The close event is fired when the WebSocket connection is closed.

But sending messages in the form of strings over raw WebSockets isn't very appealing when we're wanting to develop advanced web applications. Obviously, we're going to be using JSON to transfer data to and from the server. But how do we propagate our CDI events which are fired on the server and have them bubble up on the client?

First, we'll start with the server. I'm using the JBoss AS7 application server and embedding Jetty within my web application. Thanks to this article, I was able to easily add the latest Jetty server to my maven project (dependencies below) to get everything up and running in a few minutes.

A few things worth noting:

  • Security: Since our WebSocket server is running on a different port (8081) than our AS7 server (8080), we must account for not having the ability to share cookies, etc...
  • Proxies: As if proxy servers weren't already a huge problem for running WebSockets and HTTP over the same port, we are now running the separately (but I have a semi-solution for this below)
  • Threading: Since we're observing/listening for CDI events, we must perform some thread same operations and connection sharing.

So, if you're still reading ;) let's get on with the code.

Download the latest JBoss AS7 (7.1.0.CR1b as of this writing)

Add the Jetty maven dependencies to your project. This demo is based off of the original html5-mobile quickstart for JBoss AS7.

Next we setup the WebSocket server using Jetty's WebSocketHandler and embedding it inside a ServletContextListener. Here we're sharing a synchronized set of WebSocket connections across threads. Using the synchronized keyword, we ensure that only a single thread can execute a method or block at one time. The ChatWebSocketHandler contains a global Set of webSocket connections and adds each new connection as it's made within the Jetty server View complete source here.

Now we'll create a method to observe CDI events and send the fired "Member" events to all active connections.

The above code will observe the following event when a new Member is registered through the web interface.

Finally, we setup our WebSocket JavaScript client and safely avoid using the eval() method to execute the received JavaScript.

Here is the JavaScript code which listens for our CDI event, and executes the necessary client side code. (This is the alert popup seen in the video above.)

One additional piece I added to this approach is the use of HAProxy. This gives us a reverse-proxy on the WebSocket port (8081), in the end allowing all traffic (HTTP and ws/wss) to be sent across a central port - 8080 in this case.

As you can see, this is a very prototyped approach to achieve $SUBJECT, but it's a step forward in adding a usable programming layer on top of the WebSocket protocol. There's probably a few framework out there which try to provide a programming model on top of WebSockets, so leave comments if you know of any.

Fixing Ajax on Mobile Devices (with HTML5)

29 August 2011

Java | ajax | html5 | innerhtml |

“Not only is innerHTML bad, it is the root cause of many problems… from browser memory leaks (it destroys/replaces existing elements that may have event handlers attached) to failing completely on iOS’s Mobile Safari. Yes, that‘s right, it just flakes out.”

Read on...

Replacing Photoshop With CSS3 - Creating Styles

05 February 2011

Java | html5 |

One trendy technique that I often use in Photoshop (for buttons, nav bars, etc…) is a gradient that slightly variates from its base color with a hint of inner shadow (for highlight).
This used to be a pain in the royal ass to implement with html/css2, but now is amazingly simple with CSS3. Not only is it simple, but you can also create a sort of “gradient template“ to be reused. Kind of like a “style” which can be applied to any element in Photoshop.


First off, this is how I would normally do it in Photoshop:

  1. Create the element – a button in this case:

  2. Create your gradient. Gradients that are hardly gradients seem to give a nice appearance and body to the design. Meaning you start with a base color like #6c291f and move up the scale to #e42a00.


  3. Next you add an inner shadow to give it a glow like effect. Again this too is based on your gradient color.


  4. Here is the end result (from Photoshop):

Now, let's do the exact same thing in CSS3 with 1 step.

This tested fine across all the latest browsers (Firefox 3.6+, Latest Safari, Latest Chrome, and who cares about IE ;)

  1. Simply use the brightest part of the gradient color from above (#e42a00) and substitute it as the background color below:
     1 button.red {
    2 background: #e42a00 mozlinear-gradient(90deg, rgba(0, 0, 0, .3) 33%, rgba(255, 255, 255, .1) 123%);
    3 background: #e42a00 webkitgradient(linear, left top, left bottom, from(rgba(255, 255, 255, .1)), to(rgba(0, 0, 0, .3)));
    4 border-radius: 7px;
    5 mozborder-radius: 7px;
    6 webkitborder-radius: 7px;
    7 border: none;
    8 box-shadow: 0 0 6px rgba(255,102,102,1) inset;
    9 mozbox-shadow: 0 0 6px rgba(255,102,102,1) inset;
    10 webkitbox-shadow: 0 0 6px rgba(255,102,102,1) inset;


  2. Here is the end result (from Firefox):

Notice from the css code that we are only using one color? This is so we can easily create a super class that allows us to override its functionality. In the end all you would need is one line of code for background color to create a button for every color that exists with the same style from above applied to it.


Now to create a button using the same “style”, you would only have to create a class that defines the background color and inner shadow highlight. i.e….

1 button.lightblue {
2 background-color: #41b6ff;
3 mozbox-shadow: 0 0 6px rgba(55,243,255,1) inset;
4 }


This would give you a button like this:


The only part that isn't really flexible is the inner shadow feathering. It is currently set to blur the shadow by a fixed pixel. It would be awesome if you could blur by percent as this would allow the gradient filled element to be resized dynamically and maintain the aspect of inner glow.