Applet Javascript Bridge Example
A Sample JavaScript-Applet Bridged Client
Using the Universal Messaging nApplet, it is easy to bridge communications between a JavaScript front end which delegates all Universal Messaging communication to an Applet.
The code shown below is a fully functioning example of such a client, containing an applet along with JavaScript code which communicates seamlessly with the applet. The applet implements all connection, publishing and subscription logic. All events that are delivered to the applet are called back into JavaScript asynchronously.
<?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/nirvana.js"></script>
<script>
var appName = "myTestApplication";
var channelName = "/tutorial/testchannel/";
var realm = "nhp://" + location.hostname + ":80";
var sessionName = "myExampleSession";
var username = "TestUser"; // note that in a real app,
// this should be an authenticated username!
var connected = false;
var isLoadedCounter = 0;
var mySession = null;
var testChannel = null;
var isTimedOutConnectingCounter = 0;
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 a realm address, a sessionid,
* a username and a "prefix" for connection listener callback methods.
* The last parameter is the connection listener "prefix". As we chose
* to use the string "conHandlerCB" as the prefix, we must now implement
* four methods to receive asynchronous notifications of our connection
* status: conHandlerCBgotInitialConnection, conHandlerCBdisconnected,
* conHandlerCBreconnected and conHandlerCBtryAgain.
* Note that we could use any string as a prefix; we simply need to
* name our four implemented methods accordingly.
*********************************************************************/
// the nJSCRIPT variable is set by the applet when it initially loads
if ( typeof nJSCRIPT == "undefined" ) {
if ( isLoadedCounter > 4) {
window.status = "unable to initialise nirvana libraries";
return;
}
else{
setTimeout("isLoaded()", 4000);
}
}
else if ( nJSCRIPT == true ) {
window.status = "nApplet has been initialised.";
// session is initialised with a realm address, a sessionid,
// a username and a connection listener callback stub.
mySession = new nSessionWithSubjectAndReconnectionHandler(realm,
appName, username, "conHandlerCB");
mySession.init();
connectionTimeoutMonitor();
}
}
function connectionTimeoutMonitor() {
/********************************************************************
* This method is used to allow the web page to give up on attempting
* to get an initial connection after a certain number of retries are
* unsuccessful.
*********************************************************************/
isTimedOutConnectingCounter++;
if ( mySession.isConnected() ) {
return;
}
else if (isTimedOutConnectingCounter < 4) {
setTimeout("connectionTimeoutMonitor()", 4000);
}
else if (isTimedOutConnectingCounter == 4) {
timedOutConnecting = true;
window.status = "Timed out connecting to Nirvana. ";
document.getElementById('nirvana').stop();
return;
}
}
function conHandlerCBdisconnected() {
/********************************************************************
* This method automatically gets invoked we get disconnected from our
* Nirvana session. Note that this is because we specified
* "conHandlerCB" as the prefix of the implicit "disconnected",
* "reconnected","initialConnection" & "tryAgain" methods when we
* created the session (see fourth parameter in the constructor for
* nSessionWithSubjectAndReconnectionHandler).
* A typical use for these method would be to re-enable UI components
* which might have been disabled during the disconnected period.
* See also the tryAgain method, which allows us to specify whether
* the application should attempt to reconnect automatically after a
* disconnect has occurred.
*********************************************************************/
connected = false;
alert("Disconnected");
}
function conHandlerCBreconnected() {
/********************************************************************
* This method automatically gets invoked we get reconnected to our
* Nirvana session after a disconnect too place. Note that this is
* because we specified "conHandlerCB" as the prefix of the implicit
* "disconnected","reconnected","initialConnection" & "tryAgain"
* methods when we created the session (see fourth parameter in the
* nSessionWithSubjectAndReconnectionHandler constructor).
* A typical use for these method would be to re-enable UI components
* which might have been disabled during the disconnected period.
* See also the tryAgain method, which allows us to specify whether
* the application should attempt to reconnect automatically after a
* disconnect has occured.
*********************************************************************/
connected = true;
alert("Reconnected");
}
function conHandlerCBgotInitialConnection() {
/********************************************************************
* This method automatically gets invoked we get the initial connection.
* Note that this is because we specified "conHandlerCB" as the prefix
* of the implicit "disconnected","reconnected","initialConnection" &
* "tryAgain" methods when we created the session (see fourth parameter
* in the nSessionWithSubjectAndReconnectionHandler constructor).
* A typical use for these method would be to wait for confirmation
* that the session has initialised before continuing with any other
* processing.
*********************************************************************/
connected = true;
window.status = "Connected to Nirvana.";
setTimeout("handleNewConnection();", 500);
}
function conHandlerCBtryAgain() {
/********************************************************************
* This method automatically gets invoked after each attempt to
* reconnect to a disconnected Nirvana session. This allows the
* developer to control whether or not continued attempts should be
* made to reconnect. Note that this is because we specified
* "conHandlerCB" as the prefix of the implicit "disconnected",
* "reconnected","initialConnection" & "tryAgain" methods when we
* created the session in our isLoaded() method.
* This method allows us to specify whether the application should
* attempt to reconnect automatically after a disconnect has occured.
*********************************************************************/
return true;
}
function handleNewConnection() {
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) subscribe to the channel.
*********************************************************************/
if (connected) {
var channelAttribs = new nChannelAttributes();
channelAttribs.setName(channelName);
testChannel = mySession.findChannel( channelAttribs, "testChannelFoundCB" );
// make sure we have a usable channel object
if (testChannel == false) {
if (mySession.isConnected()) {
// Channel could not be found. Let us try again.
// Maybe channel does not exist, or channel ACL is incorrect
setTimeout("setupTestChannel()", 2000);
} else {
// waiting for disconnect
setTimeout("setupTestChannel()", 4000);
}
} else {
// Add subscriber to the channel object
var startEID = 0;
var evtHandler = "myTestChannelEventHandlerCB";
testChannel.addSubscriberFromEID(evtHandler, startEID)
}
} else {
// if we were disconnected when this method was called, try again
setTimeout("getServerTime()", 4000);
}
window.status = "";
}
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 data (which is a byte[]), and/or its "dictionary"
* which contains a set of key-value pairs. In this demo, we use the
* dictionary keys "publisher" and "message", and 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 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 publish our event to the channel.
*********************************************************************/
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);
} catch (error) {
alert("Error: " + error.message);
}
}
</script>
<title>Pub/Sub with Nirvana JavaScript</title>
</head>
<body onload="isLoaded()">
<h1>Nirvana : Pub/Sub with Java to JavaScript Bridge</h1>
<applet
codebase = "/jars/"
archive = "nClient.jar,nSigned.jar,nApplet.jar"
code = "com.pcbsys.nirvana.client.jscript.NirvanaAppletThreaded.class"
id = "nirvana"
name = "nirvana"
MAYSCRIPT
width = "0"
height = "0"
hspace = "0"
vspace = "0"
align = "bottom"
>
</applet>
<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>