original:http://martinzoldano.blogspot.com/2010/01/websockets-netty.html
Web applications have evolved significantly the past decade, we’ve all seen an evolution from thin-client with predominant client/server template-driven paradigms to newer Web2.0 RIA technologies providing smarter clients since now they can do more with plugin run-times.
So far, all requests have been orchestrated from the client ‘only’, there was no standard connectivity over the network in which the server side could push data down to the client at any point of time.
There’s a new revolutionizing (incubating) technology: WebSocket, in simple words it provides that key connectivity enhancement with full-duplex (bidirectional) communications. It basically eliminates some of the approaches like inefficient polling or long polling developers’ve been forced to implement in the past wasting redundant network bandwidth and keeping servers bloated with chatty clients.
Moreover, now that JSR315 / Servlet3.0 is being adopted by the key player server containers (example Jetty continuations) , we can see that very exciting things are evolving on the server side as well, enabling asynch-NIO + eliminating the blocking thread req/con limitation.
Even though specs on both sides are still in draft status, I decided to peek and learn by experimenting on a very simple proof of concept, inspired by few blogs out there, I thought of emulating server broadcasts to client (spawning different threads) simulating somewhat a real time scenario, so here it goes:
First the client, since not all browsers have websocket support yet, I used latest google chrome[4.0.249.43] on my linux ubuntu distribution to test drive this experiment, here’s a bare-bone straight-forward html + js client that depicts new features:
<html> <head> <title>WebSocket</title> <script> var socket; function openWebSocket() { if (window.WebSocket) { socket = new WebSocket('ws://127.0.0.1:10000/websocket'); socket.onopen = function(event) { alert('WebSocket open!'); }; socket.onclose = function(event) { alert('WebSocket closed'); }; socket.onmessage = function(event) { parse(event.data); }; } else { alert('Your browser does not support WebSockets yet.'); } } function closeWebSocket() { socket.close(); } function $(id) { return document.getElementById(id); } function send(message) { if (!window.WebSocket) { return; } if (socket.readyState == WebSocket.OPEN) { socket.send(message); } else { alert('The WebSocket is not open!'); } } function parse( response ) { // parse response: json or xml, etc $('out').innerHTML = response; } </script> </head> <body onload='openWebSocket()' onunload='closeWebSocket()'> <div id='out'></div> <!-- more html here --> </body> </html>
And on the server side, since I wanted to provide a sample project download I wanted to keep it lean and mean, when learning the new jboss messaging project hornetq I noticed that it is based on netty : client/server NIO framework for network protocols (which by the way its developer has done a great job with a clean impl, kudos! Trustin).
Below is a link to get the project, look for class EnvStatsProcessor which you will see that it spawns 3 threads (if run on linux), each writes data to corresponding channel simulating almost a real time processing per half & 1 sec sleep intervals. The http handshake + upgrade is on class WebSocketServerHandler taken from netty), modify EnvStatsProcessor for your needs, you could enhance it to send json/xml fmt, and client could then use js ajax/dom utilities, note that netty supports binary serializations fmt as well, for that you could use its client api in a rich-client like a swing app and using hessian or google protocol buffers for example.
Here’s a quick 30 sec screen-cast to see running: “Look Ma’ no polling
”
(sorry for the low res video, watch in full screen
Summary: This html-js thin-client behaves beautifully like if it was a desktop app!. Specifications are currently maturing, but the future sure looks brighter my friends
Instructions:
[1] download project here , (source is included).
[2] unzip it in local fs.
[3] cd /mypath/bin
[4] . runsvr.sh (or .bat if windows)
[5] finally launch chrome (or an html5 supported one) and open static
file:///mypath/client.html
Note: do not use http://, could have served it via http from svr but this way client is totally disconnected, and svr focuses solely on ‘ws://’ protocol.
Cheers.