Prototype for Real Time Data Streaming (Data Push) Part 2
September 23, 2012 1 Comment
This is the part 2 of the serial. Here is the other parts of the series.
Prototype for Real Time Data Streaming (Data Push) Part 1: maven2 generated Jetty based application
Prototype for Real Time Data Streaming (Data Push) Part 3: channel feeder java based application
In the part 1 of this serial, I created a project DeviceMonitort by using mvn. In the following, I will modify the web application to support multi-channels subscription based web application housing on Jetty 7 embedded server.
Multi-Channel subscription based Web Application
Web Pages
First, I will replace the index.jsp with there html files: index.html, frameleft.html and frameright.html.
index.html
<html> <head> <title>Device Monitor</title> </head> <frameset cols="30%,70%"> <frame src="frameleft.html" name="left_frame"> <frame src="frameright.html" name="right_frame"> </frameset>
frameleft.html
Here I demonstrates multiple channel selections on the left frame, and users can choose whatever predefined channels they want to subscribe. In fact, the channel name can be generalized as anything.
<html>
<head>
<title>frameleft</title>
<script language="JavaScript" type="text/javascript">
<!--
function change(channel)
{
parent.left_frame.document.form1.text1.value=channel;
parent.right_frame.location="device.jsp";
}
//-->
</script>
</head>
<body bgcolor="#ffffff" text="#000000">
<FORM name="form1">
Choose a channel from the list:
<INPUT type="text" name="text1" size="25" value="/123" readonly="readonly">
</FORM>
<a href="javascript:change('/123')">/123</a>
<br>
<a href="javascript:change('/stopwatch')">/stopwatch</a>
<br>
<a href="javascript:change('/sar')">/sar</a>
<br>
<a href="javascript:change('/iostat')">/iostat</a>
<br>
<a href="javascript:change('/vmstat')">/vmstat</a>
<br>
<a href="javascript:change('/ifstat')">/ifstat</a>
</body>
</html>
frameright.html
<HTML> <HEAD> <TITLE>Device Monitor Introduction</TITLE> </HEAD> <BODY> <p>Cometd is a project by the Dojo Fundation to implement Bayeux specification. </p> <br> <p>Bayeux is a purpose to implement responsive user interaction for web clients using Ajax and server-push technique called Comet.</p> <br> <p>The messages are routed via named channels and can be delivered server2client, client2server or client2client.</p> <br> <p>Channels are by default broadcast publish subscribe. </p> </FORM> </BODY> </HTML>
Other Files
The device.jsp file is modified from index.jsp. It allows the parameterized channelName to be passed to dev.js.
device.jsp
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<script type="text/javascript" src="${pageContext.request.contextPath}/jquery/jquery-1.7.1.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/jquery/json2.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/org/cometd.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/jquery/jquery.cometd.js"></script>
<span style="color:#ff0000;"><script type="text/javascript" src="dev.js"></script></span>
<%--
The reason to use a JSP is that it is very easy to obtain server-side configuration
information (such as the contextPath) and pass it to the JavaScript environment on the client.
--%>
<script type="text/javascript">
var config = {
contextPath: '${pageContext.request.contextPath}',
channelName: parent.left_frame.document.form1.text1.value
};</span>
</script>
</head>
<body>
<div id="body"></div>
</body>
</html>
The jquery dev.js is modified from application.js, and is called by device.jsp above, and it subscribes to config.channelName.
dev.js
(function($)
{
var cometd = $.cometd;
$(document).ready(function()
{
function _connectionEstablished()
{
$('#body').prepend('<div>CometD Connection Established</div>');
}
function _connectionBroken()
{
$('#body').prepend('<div>CometD Connection Broken</div>');
}
function _connectionClosed()
{
$('#body').prepend('<div>CometD Connection Closed</div>');
}
// Function that manages the connection status with the Bayeux server
var _connected = false;
function _metaConnect(message)
{
if (cometd.isDisconnected())
{
_connected = false;
_connectionClosed();
return;
}
var wasConnected = _connected;
_connected = message.successful === true;
if (!wasConnected && _connected)
{
_connectionEstablished();
}
else if (wasConnected && !_connected)
{
_connectionBroken();
}
}
// Function invoked when first contacting the server and
// when the server has lost the state of this client
function _metaHandshake(handshake)
{
if (handshake.successful === true)
{
cometd.batch(function()
{
cometd.subscribe(config.channelName, function(message)
{
//$('#body').append('<div>Server Says: ' + message.data + '</div>');
$('#body').prepend('<div>['+config.channelName+'] ' + message.data + '</div>');
});
// Publish on a service channel since the message is for the server only
//cometd.publish('/123', { name: 'World' });
});
}
}
// Disconnect when the page unloads
$(window).unload(function()
{
cometd.disconnect(true);
});
var cometURL = location.protocol + "//" + location.host + config.contextPath + "/cometd";
cometd.configure({
url: cometURL,
logLevel: 'debug'
});
$('#body').<span style="color:#ff0000;">prepend</span>('<div>Connecting to ['+config.channelName+']'+'</div>');
cometd.addListener('/meta/handshake', _metaHandshake);
cometd.addListener('/meta/connect', _metaConnect);
cometd.handshake();
});
})(jQuery);
By now, the multi-channel web based application is ready to go. Just start your jetty server:
mvn install jetty:start
Go to http://localhost:8080/ The following is the web application page:
For example, click channel ‘/sar’ and you will subscribe to /sar. Of course, you just get the following screen because there isn’t any data feed onto the channel.
In the next post, I will show how to develop a java application to feed data onto the channel.


