Tutorial

Tutorial: JSF 2 and HTML5 Server Sent Events

The world of HTML5 offers many features to facilitate the creation of exciting and dynamic web sites. There are web communication specifications under the HTML5 “umbrella” that define a standard way to perform real-time communication between browser clients and servers. One such specification is the Server Sent Events specification. In this article, we will explore how we can incorporate HTML5 Server Sent Events into a JavaServer Faces (JSF) User Interface using some of the new component features available since JSF 2.0.

HTML5 Server Sent Events (SSE) is a W3C specification that defines a standard API for opening an HTTP connection for receiving push notifications (data) from the server. Operationally, it works the same as Comet. However, Comet attempts to facilitate “server push” over the existing HTTP request/response protocol through various hacks such as appending scripts to iframes. The SSE specification introduces a new EventSource HTML element that can be used with JavaScript to establish a connection to a server end point. The client also registers event callback JavaScript functions for handing “pushed” data from the server. Let's look at a client example:

Listing 1: Client Page

 

 <!DOCTYPE html>
    <head>
       <script type='text/javascript'>
          var source = new EventSource('serverevents');
          source.onmessage = function(event) {
             var ev = document.getElementById('events');
             ev.innerHTML += event.data; 
          };
       </script>
   </head>
   <body>
      <div id=”events” />
   </body>

 

This example shows a simple page that will establish a connection to a server endpoint when the page is loaded. On line 4, we create a new EventSource object, feeding it the URL of a server endpoint. The server endpoint could be a PHP script, NodeJS implementation, or even a Java Servet. When a new EventSource instance is created, an initial GET request to the server endpoint is done to establish the initial connection. On line 5, we register a message callback that will populate the events div with the event data. We could have also registered a message handler on the EventSource instance this way:

 

source.addEventListener('message', 'msgCallback', false);

 

As data is pushed from the server, this callback will update the div area in the page. It is also possible to handle multiple event types from the server:

 

source.addEventListener('ticker', 'tickerCallback', false);
source.addEventListener('time', 'clockCallback', false);

 

The event data for these events would be pushed over the same EventSource connection. It should be mentioned that SSE (namely the EventSource API) is not yet available in all browsers. Google Chrome is one such browser that has SSE support.

Server Requirements

The SSE specification specifies requirements for the server response. The specification states that the response content type must be text/event-stream. To send a single line of data (Hello World!):

 

data: Hello World!\n\n

 

To send multiple lines of data:

 

data: This is the first line\n
data: This is the second line\n\n

 

Here, a single string of data concatenated with the newline character will be sent to the client side event handler function. It is also possible to send the response as JSON data:

 

data: {\n
data: "msg":"hello world",\n
data: "id:"12345\n
data: }\n\n

 

In all cases, notice that two successive newline characters end the response.

The User Interface

We'll look at a simple "Stock View" application that will cause the streaming of three event types to the JSF user interface. This user interface consists of three areas of information. The first area is the “time” bar. The second area is the stock quote area that consists of an input field to enter stock quotes, buttons to retrieve stock quote information and reset (clear) the input area, and a table that displays the stock quote information “real-time” as it is updated on the server. The quote numbers are randomly generated on the server, but real quotes could be retrieved by tying into a quote service. The third area consists of a link to retrieve RSS news feeds for the stocks, and a scrollable area that displays the news feed. The news feed is also pushed from the server “real-time”. Corresponding to these three areas are three SSE event types: time, ticker and rss. When the user interface is first displayed, the clock will tick real time. You enter space delimited stock symbols, press the Get Quotes button and a table is dynamically displayed with streaming quotes. Pressing the Get Stock News link causes news feeds to stream from the server.

The User Interface Markup

JSF 2.0 introduced three big features that make it easier to develop dynamic user interfaces.

  • Facelets becomes the primary view technology
  • Composite components make it easier to develop complex components
  • Ajax support

Let's see how these three features are used in this user interface. Listing 2 is the markup for the main user interface.

Listing 2: stock.xhtml Facelets View

 

 <!DOCTYPE html>
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h5="http://java.sun.com/jsf/composite/h5"
       xmlns:ez="http://java.sun.com/jsf/composite/stockinfo">
     <h:head>
        <meta charset="UTF-8" />
   </h:head>

   <h:body style="background: #fefeef">

      <h:form>
          <h:panelGrid styleClass="title-panel">
             <h:panelGrid columns="2" cellpadding="20">
                <h:outputText value="S t o c k V i e w" styleClass="title-panel-text"/>
             </h:panelGrid>
             <h:outputText value="Powered By JavaServer Faces 2.1 and Html 5 Server Sent Events "
                styleClass="title-panel-subtext"/>
          </h:panelGrid>

           <h:outputStylesheet name="stylesheet.css" />

           <h5:sse url="/JSFStock1/sse/stockticker" events="{stock:stockHandler,time:clockHandler,rss:rssHandler}"/>

           <br/>
           <ez:clock/>
           <br/>
           <br/>
           <ez:stock/>

           <h:messages/>

       </h:form>

   <a href="doc.xhtml">Documentation</a>
   </h:body>
 </html>

 

This user interface uses four composite components. We'll look at these in more detail later on, but I summarize them here:

  • sse: Server Sent Events component used to establish a connection to a server end point.
  • clock: Clock component displays the ticking time bar
  • stock: Stock component that produces the input field for entering stock symbols, the two buttons, and a placeholder for the dynamic table that will display stock ticker information.
  • rss: Component that produces the link Get Stock News and a placeholder for the dynamic scrollable area that will display stock news. This component is actually contained in the implementation of the stock component which is why you don't see it in this view.

The first thing you'll notice is that on line 1 we're using an HTML5 document type declaration. That makes this document an HTML5 polyglot document because it has an HTML5 document type /namespace and well-formed XHTML syntax – which works great for JSF views. This would allow us to use other HTML5 features as well. Let's take a look at the other relevant sections of this view:

Lines 3 – 7: Here we declare the namespaces used in the user interface. Lines 3 and 4 are just the standard JSF namespaces. Line 5 is the Facelets namespace. Line 6 declares the namespace that we'll use for our SSE component. Line 7 declares the namespace that will be used for the clock, stock and rss components.

 Line 25: This is the usage of the SSE component. This component uses two attributes:

  • url: The URL of the server endpoint that we are connecting to
  • events: Specifies event type : event handler pairings. The event handler is the name of the JavaScript function that will handle the associated event type data coming from the server.

Line 28: This is the usage of the clock component.

 Line 31: This is the usage of the stock component.

It's easy for a page author to use well defined components in a view. Now let's see how these components are defined.


Roger Kitain
Roger Kitain

What do you think?

JAX Magazine - 2014 - 05 Exclucively for iPad users JAX Magazine on Android

Comments

Latest opinions