WebSocket: Bringing TCP to the browser

The WebSocket standard is almost finalized. However, WebSocket itself is offering “just” a (data) pipe. WebSocket is well suited to bring event- or data-driven applications to the browser. A valid example would a Web UI for a JMS or AMQP application. With help of the Kaazing Gateway this is possible! As said before, you are basically able to bring any TCP- or UDP-based application to the web.

A simple TCP-based echo server

Since the WebSocket client API itself is not enough (to build a “real” application), we need some (existing) backend, or server. A very simple example would be to bring a (TCP) echo server to the browser, via WebSocket:

var net = require('net');

var server = net.createServer(function (socket) {

  // "on data" event listener:
  socket.on('data', function(data) {

    console.log('Got this data: ' + data)

    // Echo:
    socket.write('You said: ' + data);
  });
});

server.listen(1337, '127.0.0.1');

The above code is a VERY simple “EchoServer” that runs on port “1337″. It is in Node.js. The code is borrowed from their website.

Bring it to the Web

To be able to access this TCP server with a WebSocket application you need to add the following configuration to the Kaazing WebSocket Gateway:

<service>
  <accept>ws://localhost:8000/echo</accept>
  <connect>tcp://localhost:1337/</connect>
  <type>proxy</type>
  <cross-site-constraint>
    <allow-origin>*</allow-origin>
  </cross-site-constraint>
</service>

The entry point for the echo server is the ws://localhost:8000/echoURL. The Gateway connects the WebSocket connection to the backend (check the tcp port). The connection to the echo server is straightforward. The following shows a pretty simple JavaScript program, that opens a WebSocket connection in order to send and receive data from the underlying TCP server:

var websocketConnection = new WebSocket("ws://localhost:8000/echo");
websocketConnection.onopen = function(ev) {
	console.log('Connected to the echo service')
};
websocketConnection.onmessage = function(event) {
  var payload = event.data;
  displayEcho(payload);
};
...
websocketConnection.send("Hello Echo Server");
...

This is obviously a simple example, but it clearly shows the power of WebSocket! Give it a try!

If you are interested in HTML5 and WebSocket, check out the Kaazing Gateway! BTW. Kaazing is hiring

Bringing Stomp/JMS to the browser – via WebSocket

Last week I attended the Con-Fess conference in Vienna to speak about WebSocket (and its JSF integration). The first demo described how to bring UDP-based network traffic to the browser. Another demo from my presentation showed how to bring JMS to the browser, by using WebSocket.

You can try this out as well – The steps are quite simple:

  • Download the JMS Edition of the Kaazing gateway and extract it
  • Start the included Apache ActiveMQ server
  • Start the gateway itself
  • Start the demo stock ticker feed
The Java program behind the “stock.start” script is a simple class, which uses the standard JMS API to send messages (stock prices) to the running Apache ActiveMQ. We now need a browser-based JavaScript client, which talks to the Apache ActiveMQ over WebSocket.
The Kaazing Gateway (JMS edition) comes with a JMS API for various platforms, like JavaScript or Flash/ActionScript. If you have ever programmed something that used JMS, you are able to use it!
Let’s have a look how to setup a connection to the JMS server:
...
var stompConnectionFactory =
        new StompConnectionFactory( "ws://localhost:8000/jms");

// create a connection, by using a JS callback
var connectionFuture =
   stompConnectionFactory.createConnection(user, passwd, function () {

    if (!connectionFuture.exception) {
        connection = connectionFuture.getValue();
        // register a JMS exception handler
        connection.setExceptionListener(handleException);

        // create session
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        // create a topic
        topic = session.createTopic("/topic/destination");

        // creating some consumers!
        var consumer1 = session.createConsumer(topic);

        // attach the callback that receives the stock prices:
        consumer1.setMessageListener(handleMessageCallback);

        // start!
        connection.start(someCallback);
    }
....
});
The code is straightforward: A (Stomp)ConnectionFactory is created and we use that factory object to create the actual connection. The createConnection() function takes three arguments: user, password and a callback, which is invoked once the connection has been established (or an exception is thrown). If no exception occurred, the code executes a few steps:
  • we receive the actual connection
  • we setup a JMS exception handler
  • we create a session, a JMS topic and a consumer
  • we register a handler for the incoming JMS messages (handleMessageCallback)
  • we finally start the connection’s delivery of incoming messages
The handleMessageCallback() is used to receive the stock prices and to “draw” the DTHML, so that the stock changes are nice to watch in a vanilla HTML table, like below:
The code for the message listener is also using our JavaScript JMS API, to receive JMS (Text)messages:
function handleMessageCallack(message) {

  // did Apache ActiveMQ send us a JMS TextMessage?

  if (message instanceof TextMessage) {
     var body = message.getText();

     // DHTML code to show stock values...

  }
}

The above JavaScript code is pretty much readable for every JMS coder. The big news is that the JMS communication from the ActiveMQ to the browser (and vice versa) happens over WebSocket. This dramatically reduces overhead and latency for your web application!

The WebSocket gateway is not limited to Stomp/JMS, it has support for other protocols like AMQP, or even XMPP as well!

If you want to try (or see) this stock ticker, you can! It is part of the Kaazing JMS demo bundle. Once you installed the gateway, you can see the stockticker on your machine

Have fun!

input type:file issues with Firefox 3.0

Today I had the joy to figure out about (at least) two issue in Firefox 3.0. They are working fine in Firefox 3.5 and later. The problems are

  • CSS styling does not work
  • JavaScript focus() calls do not work

After some searching and “testing” I learned, that these are actually known Firefox 3.0 bugs:

This can be simply seen with a small test-case:

<html>
<head>
<script type="text/javascript">
function fc()
{
var element = document.getElementById("filer");
try
{
element.focus();
}
catch(e)
{
alert(e);
}
}
</script>
</head>
<body>
<input id="filer" onfocus="alert('set focus on inputFile');" type="file" style="border: 2px solid #C70000;"/>

<button id="btn" onclick="fc();">Focus input file</button>
</body>
</html>

Since the support for Firefox 3.0 died in March 2010 I feel it is not worth to waste time in fixing this by adding nasty hacks/work-arounds. Maybe there are simply hacks – if so, let me know :-)

Yes… something like this could be done… but the focus/style works in FF2 and FF3.5/6 without any of those hacks; and the button is not what we are interested in styling…

Client side logging with JavaScript and ADF Faces

ADF Faces is using (on the server) a “wrapper” around the standard Java logging. Based on the given log-level, the server-side console “prints” out different messages. To make life (and debugging) easier we did a similar thing for the client-side: ADF Faces contains a rich client-side Logger API. In order to use it, you need to enable it inside of the web.xml file, like:

<context-param>
 <param-name>oracle.adf.view.rich.LOGGER_LEVEL</param-name>
 <param-value>WARNING</param-value>
</context-param>

Now you can also start to use the LOGGER API in your custom JavaScript code, like:

AdfLogger.LOGGER.logMessage(AdfLogger.SEVERE, "This is from your logger!");

This is really a nice feature. When running with Firebug, you see the messages inside of the FB console!

Nice inline JavaScript and CSS via ADF Faces resource tag

Sometimes it is required that you need (or want) to write some custom JavaScript (and/or CSS). In JSF2 there are two tags to refer to JavaScript and CSS files. While the functionally to seamlessly integrate (external) resources, not always you really want to create an external file for that stuff…

ADF Faces has a nice <af:resource> tag which gives you a good amount of flexibility to write embedded JS. Sure you can also reference to external files as well:

<af:resource type="javascript">
function myJavaScriptFunction()
{
// do stuff in here...
}
...
</af:resource>

This is pretty nice, since you can edit stuff inside of the page. If you figure the CSS (or JavaScript) is getting bigger and bigger, you can always stick it into an external file and reference it with the source attribute of the <af:resource> tag.

Mobile Development with Apache MyFaces Trinidad

Since smartphones, like iPhone or Android phones, are getting more and more popular, more companies are getting serious about a “mobile strategy”. JavaServer Faces is a natural fit, since it’s rich component model allows you to simply switch the renderer… Yes you could introduce new tags/components for that, but’s that for sure an anti-pattern.

Apache MyFaces Trinidad is offering “mobile” support for a bunch of interesting devices, including Android, Microsoft Windows Mobile 5 and 6, or Apple’s iPhone. When companies want to offer a mobile version, they don’t just want “modern” phones… Consumer phones are still common and therefore used by potential customers. However supporting the wide range of different phones is not trivial: Some phones support JavaScript with Ajax, some without… Some have no JavaScript, some have a bad performance etc. All not to easy to deal with, when you have to do it from scratch!

The Apache MyFaces Trinidad renderkit covers that for your convenience, since it handles JavaScript free fallback during mobile rendering! Basically Trinidad assigns the JavaScript capability for a few mobile user-agents to ‘none’ in their capability files (Trinidad maintains a capability file for each/several user-agents). Fellow committer Mamallan is describing technical details here, on a thread to discuss “Apache MyFaces – JS free JSF” for Google Summer of Code.

Not only the capability of JavaScript is different, the size of the screen and the (native) look-and-feel differ as well. To archive a nice and almost native way of rendering ONE PAGE on different phones, (mobile) web developers use the the Skinning facility of Trinidad. Users/Developers have to create phone specific CSS files (every SDK has a tutorial for that, like Apple for its iPhone). Trinidad is able to switch the Skin during runtime. So you could use an EL and some code to attach the right skin, via user-agent detection.

Besides the device-specific CSS creating (and detaching) a custom skin is fairly easy. In the trinidad-config.xml you have the following:

<skin-family>#{agentUtil.phoneFamily}</skin-family>

The trinidad-skins.xml file, which contains would look like:

...
<skin>
<id>iphone</id>
<family>iphoneFamily</family>
<render-kit-id>org.apache.myfaces.trinidad.desktop</render-kit-id>
<style-sheet-name> iPhone/iPhone.css </style-sheet-name>
</skin>
...

While the “phoneFamily()” method in the underlying JavaBean would do something like:

public String getPhoneFamily()
{
FacesContext fc = FacesContext.getCurrentInstance();
HttpServletRequest req =
(HttpServletRequest)fc.getExternalContext().getRequest();
//Get the User Agent string from the browser
String agent = req.getHeader("User-Agent");
// Prints out user agent.  Comment out the line below for production system
if (agent != null && agent.indexOf("iPhone") > -1)
{
// If iPhone is returned.
// Comment out the followling line for production system
return IPHONE_SKIN;
 }
...

Tipp: You can ship your skins in a JAR, so that multiple (mobile) applications could benefit from the work!

Once that all is done, you are good to go! The source code of the JSPX/XHTML pages look like regular Trinidad pages! No new tags/components are required! That’s a good news, since you can leverage the knowledge you gained.

So to give an idea how rich your page could look on different phones, below are some screenshots:


This screenshot has also some information about the Trinidad TAGs that are used.

There my iPod touch and my (old ;-) ) Nokia phone:

The both show the same page, just with a different style sheet. The JSPX page is not different. All the magic is done by the Trinidad Skinning-Engine.

The ADF mobile team at Oracle put together a nice tutorial, which contains a decent demo application. It includes already some Skinnings for different mobile phones. So the getting started is fairly simple with that demo! The Trinidad developers guide has also some resources on mobile JSF development.

Generally the Trinidad library offers a pretty decent and stable framework-core (besides the 100+ components). Without its rock-solid architecture doing mobile applications would be way more odd (or complicated)!

Enjoy!

Demo of Apache MyFaces 2 and OpenWebBeans

Recently the Apache MyFaces project released its second beta release and yesterday the Apache OpenWebBeans project released its M4 release.

These are great milestones in the direction of JavaEE at Apache!

A few month ago Bernd Bohmann and I were giving a JSF2 + X presentation in Muenster, at the JUG. The presentation was great and we showed a lot of cool features of JSF2 and CDI. The big plus was that we were Apache projects (MyFaces and OWB), which we build from the trunk. Now since there are these important milestones, I was able to actually make the demo project available under my “facesgoodies” demo/kickstart project.

Get the source of the Maven project from here.

Once you extracted the source, just run “mvn” and Maven downloads all you need!

Enjoy!

Pushing realtime updates for your backend to ADF Faces

Imagine you have some services which frequently triggers your backend to process some data and you need to display these changes on the UI… The most reasonable pattern is using Comet!

ADF Faces has great and flexible support for Comet with its ADS facility. This post quickly describes you to push data from a backend to your client. In order to avoid writing and faking a “busy” backed, I use the twitter update stream – which actually provides data in REALTIME to your application.

The previous blog described the pattern how to connect to the Twitter streaming, by using Apache Wink (a REST client API).

Now within the “while loop” you need to notifiy ADS that a new tweet is waiting to be displayed by the client, like:

while(condition)
{
 // parse the input stream's JSON to nick, tweetMsg etc

 listener.onTweet(new TweetBean(nick, image, tweetMsg));
}

So from the “Twitter backend” you notify a listener that a new tweet arrived on the realtime twitter stream.

The easiest way to combine Twitter and ADS is by using the “Proxy approach”. Let your own ActiveCollectionModelDecorator class implement an interface such as “ITwitterUpdateListener”.  So, the above “listener” is actually this class. The code for the onTweet() finally creates and submits the ADS event(s):

public void onTweet(TweetBean tweet)
{
 // start the preparation for the ADS update
 atm.prepareDataChange();

 // create an ADS event.....
 // this class is not part of the API
 ActiveDataUpdateEvent event =
 ActiveDataEventUtil.buildActiveDataUpdateEvent(
// type of the event
 ActiveDataEntry.ChangeType.INSERT,
// the changeCount
 atm.getCurrentChangeCount(),
// rowKey
 new Object[] {tweets.indexOf(tweet)},
// insert at ...
 new Object[] {tweets.indexOf(tweet)-1},
// attribute/property names that change
 new String[] {"image", "nick", "message"},
// the payload for the above attributes
 new Object[] {
tweet.getImage(),
tweet.getNick(),
tweet.getMessage() }
 );

 // deliver the new Event object to the ADS framework
 atm.notifyDataChange(event);
}

Now you can use the <af:table> component to display the information of the tweets. In the example, we show the name and the picture of the poster and the
actual tweet message:

<af:table value="#{bean.activeCollectionModelDecoratorImpl}"
var="tweet" id="t1" ...>

 <af:column width="50" id="c2">

<af:outputText  escape="false"
value="#{tweet.image}" id="ot2"/>

</af:column>

<af:column headerText="USER" id="c1">
 <af:outputText value="#{tweet.nick}" id="ot1"/>
 </af:column>
 <af:column width="350" headerText="Message" id="c3">
 <af:outputText value="#{tweet.message}" id="ot3"/>
 </af:column>
</af:table>

Note: For the image we say escape:false as we stream HTML of the actual twitter location. Note that usually this can be dangerous on all outputText (cross site scripting),but here we want it, since it is a fast way to resolve the IMG…

ADF Faces and ADS is a powerful tool and you can observe twitter trends with out issues! However note that on observing twitter trends, you are kinda spammed by the backend… Therefore you need to think about the “load” of information that your user is potentially interested in..

Another interesting example on how to combine Twitter and “real time ADF Faces” is here. However the only thing there that is not really realtime is that the code polls twitter, which is fine since not all features are yet supported by the Twitter Streaming API!

Generally: This can not be used with Twitter only… You could also connect your 11g database nofifications to push data to the UI. Did that with Frank Nimphius for OpenWorld. (Not sure if his blog actually has the demo code).

Enjoy!

Twitter Streaming API and Apache Wink

During 2009 Twitter launched their Streaming API, which allows developers to get an (almost) real-time notification of tweets. The “filter.json” resource allows some filtering of the content. With CURL you could listen to the Twitter stream like:

curl http://stream.twitter.com/1/statuses/filter.json?track=myKeyWord -umyUserAccount:password

Note that the track parameter could be also send to the stream.twitter.com server (which is a Jetty-powered service) as a POST (-d option).

To have a bit more comfort, one wants to use a (Java) REST API. Apache Wink is pretty nice and listening to the stream is simple:

ClientConfig cc = new ClientConfig();

String logon = "myAccount:myPasswd";
String encodedLogon = new BASE64Encoder().encode(logon.getBytes());

RestClient client = new RestClient(cc);
Resource twitter = client.resource("http://stream.twitter.com/1/statuses/filter.json?track=Berlin");

twitter.header("Authorization", "Basic " + encodedLogon);
twitter.contentType(MediaType.APPLICATION_FORM_URLENCODED_TYPE);
twitter.accept(MediaType.APPLICATION_JSON_TYPE);

// do the HTTP GET
ClientResponse cr = twitter.get();

// we want the input stream
InputStream is =  cr.getEntity(InputStream.class);

try
{
BufferedReader r = new BufferedReader(new InputStreamReader( is, "UTF8"));
while(someCondition)
{
String rawJsonTweetData = r.readLine();
// parse the tweet and submit to your "system"
...

Once you submitted the HTTP_GET you need to transform the returned value to be InputStream. Now the stream is in your hand and you can parse the returned JSON value as you like. From there you can use the streamed data in your system.

I used the stream value to visualize the data with ADF Faces’ comet facility (aka ADS). I created a simple monitoring processor, which receives the tweets and submits them to the ADS subsystem. From there I “pushed” them to the browser, so my ADF Faces table got updated, with the latest tweets.

Note: “Following” a Twitter trend key-word can generate quite a huge amount of data, which could flood your UI (or other processing (sub)system)

There are some libraries available that give similar access to the streaming API. I found the TweetStream Ruby GEM pretty interesting, as you can run it as daemon.