My name is Sagar Ganatra and I'm from Bangalore, India. I'm currently employed with Adobe India and I work there as a ColdFusion Engineer. At Adobe, I have worked on various features of ColdFusion and ColdFusion Builder. I'm very much passionate of web technologies and have a very good understanding of jQuery, Flex, HTML5, Java and of course ColdFusion. Sagar H is a DZone MVB and is not an employee of DZone and has posted 38 posts at DZone. You can read more from them at their website. View Full User Profile

Server sent events with HTML5 and ColdFusion

03.31.2011
| 5621 views |
  • submit to reddit
There are several ways to interact with the server apart from the traditional request\response and refresh all protocol. They are polling, long polling, Ajax and Websockets (pusherapp). Of all these Ajax and Websockets have been very popular. There is another way to interact with the server such that the server can send notifications to the client using Server Sent Events (SSE). SSE is a part of HTML5 spec: http://dev.w3.org/html5/eventsource/


What are Server Sent Events (SSE)

The specification says "API for opening an HTTP connection for receiving push notifications from a server in the form of DOM events. The API is designed such that it can be extended to work with other push notification schemes such as Push SMS."

Server Sent Events operate over HTTP and it provides an interface 'EventSource'. Web applications can subscribe to an EventSource and receive updates from the server side i.e. the server can push data to the clients as and when it wishes to do so. 


Why not Websockets?

Websockets are very useful in designing various applications such as Chat applications, Games etc,. where in communication takes place over a bi-directional channel between the client and server. However in applications such as Stock ticker, Feed reader the server responds with a message to the client and client receives it and shows it to the user. In such applications the client doesn't post a message very often. In these scenarios SSEs are very useful. Another advantage of using SSEs over Websockets is that it operates over HTTP meaning it doesn't require a special protocol or any server side implementation.


An Example of SSEs with ColdFusion

As mentioned earlier the web application can subscribe to the server using the EventSource interface. So in my javascript I have this code:
var source = new EventSource('outputMessages.cfm');
It's very simple. We are subscribing to the server side code which is  'outputMessages.cfm'.  Once the connection is successful, the client can then start receiving messages from the server. The EventSource object has the following event listeners: message, open and error.
source.addEventListener('message', function(e){

document.body.innerHTML += e.data + "<br>";

});

source.addEventListener('open', function(e){

alert('open')

}, false);

source.addEventListener('error', function(e){

if (e.eventPhase == EventSource.CLOSED) {

alert('closed')

}

}, false);
he EventSource object can then run these scripts in the background with out blocking any scripts. After establishing the connection with the server, the 'onopen' event will be fired and the client is ready to receive the messages from the server. If the server responds with the message then the 'onmessage' event will be fired and it's corresponding event handler will be executed. The 'onerror' event would be fired when the server has completed its execution and as it is observed in the above code the state of the EventSource object would be set to CLOSED. 


The EventSource object expects the server to send data with MIME type text/event-stream and the data will be sent in the following format:
data: Your message here \n\n
It expects the string 'data:' and then the message and then end of line character. The extra end of line character marks the end of message i.e. users can send multiple data lines in this way and then send the end of line character to mark the end of message. The below cfm file does just that:

<cfcontent type="text/event-stream">

<cfsetting requesttimeout="60">



<cffunction name="sendData">

<cfoutput>data: #timeFormat(now(), "medium")# #Chr(10)#</cfoutput>

<cfoutput>data: End of this message #Chr(10)#</cfoutput>

<cfoutput>#Chr(10)#</cfoutput>

<cfflush>

</cffunction>



<cfloop from="1" to="50" index="i">


<cfset sendData()>

<cfthread action="sleep" duration="1000"/>


</cfloop>
The cfcontent tag sets the MIME type to text/event-stream and then the requestTimeout is set to 60 seconds. The function sendData is called 50 times (in cfloop) and will output the data to the client every second. The third cfoutput sends just the end of line character marking the end of message.

The loop would run for 50 seconds and once the served side program has completed its execution the state of the EventSource object would be set to CLOSED. The client then reestablishes the connection with server after 3 seconds and the same loop will be executed again.

SSEs can be of great help in reducing the bandwidth and in cases where the client wants to post some data then the XHR object comes in handy.

References
Published at DZone with permission of Sagar H Ganatra, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)