This is archived documentation for an older version of Nirvana (v3.1). Please refer to documentation for the latest version if required.

WebExpress Implementations

A Sample JavaScript / Ajax Client

webExpress makes it easy to implement JavaScript Publish & Subscribe clients.

The code shown below is a fully functioning example of such a client, containing JavaScript connection, publishing and subscription logic and an HTML UI.

Try it: Download the Nirvana Sample Web Clients Pack.

<?xml version="1.0" encoding="UTF-8"?>
<!doctype html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
<script language="JavaScript" src="lib/nirvanaAsyncObjJSNotation.js"></script>

<script>

var applicationName = "myTestApplication";
var channelName = "/tutorial/testchannel/";
var realm = "http://" + location.hostname + "/sv/nvLite";
var sessionName = "myExampleSession";
var username = "emcdaid2"; // note that in a real app,
 // this should be an authenticated username!
var initialiasedASession = false;

var mySession = null;
var testChannel = null;


function isLoaded() {

 /********************************************************************
 * As soon as the page loads, we should create our Nirvana session.
 * This method is invoked by the <body> tag's "onload" event.
 * We initialise our session by passing in the names of two custom
 * methods (which, like all such callback methods in this demo, we are
 * free to name as we wish; we simply have to implement the methods).
 * The first one ("sessionInitCB") is invoked if and only if the
 * session creation was successful.
 * The second one ("sessionRejectCB") is invoked if and only if the
 * session creation failed for some reason.
 *********************************************************************/
 mySession = new nSession(realm, sessionName, username, "connectionCB", applicationName);
 mySession.init("sessionInitCB", "sessionRejectCB");

}

function connectionCBDisconnected(){

 /********************************************************************
 * This method automatically gets invoked if/when we get disconnected.
 * Note that th is is because we specified "connectionCB" as the prefix
 * of the implicit "Disconnected" and "Reconnected" methods when we
 * created the session (see fourth parameter in nSession constructor).
 * A typical use for this method might be to disable UI components
 * related to publishing (or to otherwise inform the user).
 *********************************************************************/

 alert("Disconnected");
}

function connectionCBReconnected(){

 /********************************************************************
 * This method automatically gets invoked if/when we get reconnected.
 * Note that this is because we specified "connectionCB" as the prefix
 * of the implicit "Disconnected" and "Reconnected" methods when we
 * created the session (see fourth parameter in nSession constructor).
 * A typical use for this method would be to re-enable UI components
 * which might have been disabled during the disconnected period.
 *********************************************************************/

 alert("Reconnected");
}

function sessionInitCB(){

 /********************************************************************
 * This method automatically gets invoked when our mySession object
 * is initialised. Note that this is because we specified
 * "sessionInitCB" as the name of the "callback" method which should
 * be executed after mySession.init completes.
 *********************************************************************/

 initialiasedASession = true;
 window.status = "Session Initialised";
 setupTestChannel();
}

function setupTestChannel() {

 /********************************************************************
 * Here we create an nChannelAttributes object, setting its name to
 * that of the channel we wish to use. We then use our session to
 * a) find the channel, then b) asynchronously invoke a method of our
 * choice ("testChannelFoundCB") with the resulting channel object.
 *********************************************************************/

 var channelAttribs = new nChannelAttributes();
 channelAttribs.setName(channelName);
 mySession.findChannel( channelAttribs, "testChannelFoundCB" );
}


function testChannelFoundCB(chan) {

 /********************************************************************
 * This method automatically gets invoked when mySession.findChannel
 * completes (since we specified "testChannelFoundCB" as the callback
 * in the above method. Note that the found channel object is
 * automatically passed in as a parameter.
 *********************************************************************/

 testChannel = chan;
 if( testChannel == false ) {

 /****************************************************************
 * Oops. The channel could not be accessed for some reason.
 * Try again in 500ms, say:
 *****************************************************************/

 setTimeout("setupTestChannel()", 500);

 } else {

 /****************************************************************
 * The channel is valid, so let us subscribe and receive events
 * from it. We shall specify that:
 *
 * a) the method "testChannelSubscriptionCompleteCB" should be
 * invoked automatically when the subscription initialises,
 *
 * b) all consequent events received from the channel will
 * automatically be passed as arguments to the method
 * "myTestChannelEventHandlerCB".
 *
 * Of course, we now have to implement both of these methods too.
 *****************************************************************/

 var startEID = 0;
 var evtHandler = "myTestChannelEventHandlerCB";
 var subsCB = "testChannelSubscriptionCompleteCB";
 testChannel.addSubscriberFromEID(evtHandler, startEID, subsCB);

 }
}


function sessionRejectCB(){

 /********************************************************************
 * This method automatically gets invoked iff mySession.init fails
 * (since we specified "sessionRejectCB" as the callback method to be
 * invoked after failure (due, for example, to excessive connections).
 *********************************************************************/

 alert("Session Rejected");
}

function myTestChannelEventHandlerCB(event) {

 /********************************************************************
 * This method automatically gets invoked every time we receive an
 * event from the testChannel (since this is the method we specified
 * when we subscribed - see testChannelFoundCB method). Note that the
 * event object will be passed to this method as a parameter. We can
 * then get the event's data "dictionary", and read the value of any
 * of its keys. In this demo, we use this data to update a textarea.
 *********************************************************************/

 var dictionary = event.getDictionary();
 var newData = dictionary.get('publisher') + ": " + dictionary.get('message') + "\n"
 var oldData = document.getElementById("outputTextarea").value;
 document.getElementById("outputTextarea").value = newData + oldData;
}

function testChannelSubscriptionCompleteCB(){

 /********************************************************************
 * This method automatically gets invoked when we successfully
 * subscribe to testChannel (since this is the method we specified
 * when we subscribed - see testChannelFoundCB method).
 *********************************************************************/

 window.status = "Successfully subscribed to testChannel";

}

function publishMessage() {

 /********************************************************************
 * This method is an example of how to publish events to our channel.
 * We first create an nConsumeEvent, and assign it an nEventProperties
 * object (which represents a data"dictionary" - essentially a hash of
 * key-value pairs). Finally, we call the channel's publish method,
 * passing in the event along with (optionally) the name of a callback
 * method to be invoked upon completion of the publishing attempt.
 * It is good practice to wrap code like this in try/catch blocks.
 *********************************************************************/

 if (document.getElementById("demoInput").value == "") return;
 try {
 var evt = new nConsumeEvent();
 var dictionary = new nEventProperties();
 dictionary.put("publisher", username);
 dictionary.put("message", document.getElementById("demoInput").value);
 evt.setDictionary(dictionary);
 testChannel.publish(evt, "postPublishCB");
 } catch (error) {
 alert("Error: " + error.message);
 }
}

function postPublishCB() {

 /********************************************************************
 * This method automatically gets invoked after we successfully
 * publish to testChannel (since this is the method we specified
 * when we called testChannel.publish in our publishMessage() method).
 * A typical use for this method would be to re-enable UI components
 * that might have been disabled while publishing took place.
 *********************************************************************/
 if(!initialiasedASession) alert("We did not get a session to Nirvana");
 document.getElementById("demoInput").value = "";
 window.status = "Published";
}



</script>
<title>Nirvana webExpress: Pub/Sub with JavaScript</title>
</head>

<body onload="isLoaded()">
<h1>Nirvana webExpress: Pub/Sub with JavaScript</h1>

<form onsubmit="publishMessage(); return false;">

 <h2>Input</h2>
 <input type="text" id="demoInput"/>
 <input type="submit" value="Publish">

 <h2>Output</h2>
 <textarea id="outputTextarea" rows="10" cols="70"></textarea>

</form>

</body>
</html>