Javascript Examples : Chat Application

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.

In some circumstances you may wish to serve your web application from another web server (e.g. Apache). webExpress supports this also but due to security restrictions within browsers it requires that your application is organised differently.

<?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/nClient.js"></script>

<script>

var applicationName	= "myTestApplication";
var channelName 	= "/tutorial/testchannel";
var cometpath		= "/sv";	// this is the URL File Path of a webExpress Plugin on the realm
var sessionName 	= "myExampleSession";
var username 		= "TestUser"; 	// 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  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(null, cometpath, 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>

Share this page with others:
Tell Your Tweets Facebook It! Add to Delicious Reddit! Digg It! Stumble Upon Add to Your Faves Mixx it
Follow Us:
Keep up with my-Channels on Twitter Become a fan on Facebook LinkedIn Profile Recent Highlights RSS Feed