A Step-by-Step Tutorial of Building a Simple Peer-to-Peer WebSocket App – Part 3

In Part 1, we looked at the completed application, then reviewed the starting code in Part 2. Now, let’s get started with building our application.

Point your browser to the starting state: http://jsfiddle.net/R5qc3/.

Task 1: Adding the slider to the HTML page

Add a slider to the HTML page. First, add a div, and then an input tag, of type range. As the slider changes, we invoke the sliderChange() JavaScript function and pass in the value of the slider as a parameter.

[sourcecode language=”html” light=”true” gutter=”0″]
<div id="sliderDiv">
<input id="slider" type="range" min="0" max="1200" value="600" onchange="sliderChange(this.value)" />
</div>
[/sourcecode]

The completed HTML file looks as follows:

[sourcecode language=”html” highlight=”3,4,5″ wraplines=”false”]
<body onload="doConnect()">
<!– Task 1 –>
<div id="sliderDiv">
<input id="slider" type="range" min="0" max="1200" value="600" onchange="sliderChange(this.value)" />
</div>
<!– Task 1 –>
<div id="logMsgs"></div>
</body>
[/sourcecode]

To see the updated code in JSFiddle, point your browser to the Task 1 state: https://jsfiddle.net/kaazing/6r9qcc14/. Run the app, and notice that the slider displays in the Results pane (located in the bottom right corner of JSFiddle).

Note: Notice the pattern: for “Task ” the JSFiddle URL with the saved changes is http://jsfiddle.net/R5qc3/.

Task 2: Creating the sliderChange() JavaScript function

Let’s create the JavaScript function, called sliderChange(), that fires every time the slider changes. In this step, we’ll print log information that the slider’s value has changed.

[sourcecode language=”javascript” light=”true”]
var sliderChange = function(sliderValue){
consoleLog(‘Slider changed: ‘ + sliderValue);
};
[/sourcecode]

Here’s the entire JavaScript file. Look for Task 2 in the comments to find the newly added sliderChange() function.

[sourcecode language=”javascript” collapse=”1″ highlight=”44,45,46″ wraplines=”false”]
// Variables you can change
//
var WEBSOCKET_URL = "wss://demos.kaazing.com/jms";
var TOPIC_NAME = "/topic/myTopic";
var IN_DEBUG_MODE = true;
var DEBUG_TO_SCREEN = true;

// WebSocket and JMS variables
//
var connection;
var session;
var wsUrl;

// Variable for log messages
//
var screenMsg = "";

// JSFiddle-specific variables
//
var runningOnJSFiddle = (window.location.hostname === "fiddle.jshell.net");

// Used for development and debugging. All logging can be turned
// off by modifying this function.
//
var consoleLog = function(text) {
if (IN_DEBUG_MODE) {
if (runningOnJSFiddle || DEBUG_TO_SCREEN) {
// Logging to the screen
screenMsg = screenMsg + text + "<br>";
$("#logMsgs").html(screenMsg);
} else {
// Logging to the browser console
console.log(text);
}
}
};

var handleException = function(e) {
consoleLog("EXCEPTION: " + e);
};

// *** Task 2 ***
var sliderChange = function(sliderValue) {
consoleLog("Slider changed: " + sliderValue);
};
// *** Task 2 ***
// Connecting…
//
var doConnect = function() {
// Connect to JMS, create a session and start it.
//
var jmsConnectionFactory = new JmsConnectionFactory(WEBSOCKET_URL);
try {
var connectionFuture = jmsConnectionFactory.createConnection(”, ”, function() {
if (!connectionFuture.exception) {
try {
connection = connectionFuture.getValue();
connection.setExceptionListener(handleException);

consoleLog("Connected to " + WEBSOCKET_URL);
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

connection.start(function() {
// Put any callback logic here.
//
consoleLog("JMS session created");
});
} catch (e) {
handleException(e);
}
} else {
handleException(connectionFuture.exception);
}
});
} catch (e) {
handleException(e);
}
};
[/sourcecode]

Run the modified app, and notice that as you move the slider, the log messages are printed right underneath it.

[sourcecode language=”text” light=”true”]
Connected to wss://demos.kaazing.com/jms
JMS session created
Slider changed: 616
Slider changed: 626
Slider changed: 637
Slider changed: 647
Slider changed: 658
Slider changed: 668
[/sourcecode]

To see and run the updated code in JSFiddle, point your browser to the Task 2 state: https://jsfiddle.net/kaazing/x0myk4y1/.

Task 3: Creating a topic

Now, let’s create a topic (or if the topic already exists, get a handle of the topic). Topics in the world of Java Message Service (JMS) serve as a distribution mechanism for publishing messages that are delivered to multiple subscribers. In our case, the publisher will be our app, and the subscriber will be any number of browser windows, running the same HTML5 application.

We will first invoke the createTopic() function on the session object and create a log entry about the successful creation of the topic.

[sourcecode language=”javascript” light=”true”]
var myTopic = session.createTopic(TOPIC_NAME);
consoleLog(‘Topic created…’);
[/sourcecode]

Here’s the entire JavaScript file. Look for Task 3 in the comments to find the newly added createTopic() function.

[sourcecode language=”javascript” collapse=”1″ highlight=”64,65,66″ wraplines=”false”]
// Variables you can change
//
var WEBSOCKET_URL = "wss://demos.kaazing.com/jms";
var TOPIC_NAME = "/topic/myTopic";
var IN_DEBUG_MODE = true;
var DEBUG_TO_SCREEN = true;

// WebSocket and JMS variables
//
var connection;
var session;
var wsUrl;

// Variable for log messages
//
var screenMsg = "";

// JSFiddle-specific variables
//
var runningOnJSFiddle = (window.location.hostname === "fiddle.jshell.net");

// Used for development and debugging. All logging can be turned
// off by modifying this function.
//
var consoleLog = function(text) {
if (IN_DEBUG_MODE) {
if (runningOnJSFiddle || DEBUG_TO_SCREEN) {
// Logging to the screen
screenMsg = screenMsg + text + "<br>";
$("#logMsgs").html(screenMsg);
} else {
// Logging to the browser console
console.log(text);
}
}
};

var handleException = function(e) {
consoleLog("EXCEPTION: " + e);
};

// *** Task 2 ***
var sliderChange = function(sliderValue) {
consoleLog("Slider changed: " + sliderValue);
};
// *** Task 2 ***
// Connecting…
//
var doConnect = function() {
// Connect to JMS, create a session and start it.
//
var jmsConnectionFactory = new JmsConnectionFactory(WEBSOCKET_URL);
try {
var connectionFuture = jmsConnectionFactory.createConnection(”, ”, function() {
if (!connectionFuture.exception) {
try {
connection = connectionFuture.getValue();
connection.setExceptionListener(handleException);

consoleLog("Connected to " + WEBSOCKET_URL);
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

// *** Task 3 ***
// Creating topic
var myTopic = session.createTopic(TOPIC_NAME);
consoleLog("Topic created…");
// *** Task 3 ***
connection.start(function() {
// Put any callback logic here.
//
consoleLog("JMS session created");
});
} catch (e) {
handleException(e);
}
} else {
handleException(connectionFuture.exception);
}
});
} catch (e) {
handleException(e);
}
};
[/sourcecode]

Run the modified app, and notice the log message indicating that the topic has been created.

[sourcecode language=”text” light=”true”]
Connected to ws://tutorial.kaazing.com/jms
Topic created…
JMS session created
[/sourcecode]

To see and run the updated code in JSFiddle, point your browser to the Task 3 state: https://jsfiddle.net/kaazing/Ln42y9xn/.

Task 4: Creating the producer

In this task we create a producer. The producer or publisher in the JMS world is a client that creates and sends messages. Let’s call our producer topicProducer and invoke the createProducer() function on the session object. When done, let’s create a log message indicating the successful creation of the producer.

[sourcecode language=”javascript” light=”true”]
topicProducer = session.createProducer(myTopic);
consoleLog(‘Topic producer created…’);
[/sourcecode]

Here’s the entire JavaScript file. Look for Task 4 in the comments to find the newly added createProducer() function.

[sourcecode language=”javascript” collapse=”1″ highlight=”66,70,71″ wraplines=”false”]
// Variables you can change
//
var WEBSOCKET_URL = "wss://demos.kaazing.com/jms";
var TOPIC_NAME = "/topic/myTopic";
var IN_DEBUG_MODE = true;
var DEBUG_TO_SCREEN = true;

// WebSocket and JMS variables
//
var connection;
var session;
var wsUrl;

// Variable for log messages
//
var screenMsg = "";

// JSFiddle-specific variables
//
var runningOnJSFiddle = (window.location.hostname === "fiddle.jshell.net");

// Used for development and debugging. All logging can be turned
// off by modifying this function.
//
var consoleLog = function(text) {
if (IN_DEBUG_MODE) {
if (runningOnJSFiddle || DEBUG_TO_SCREEN) {
// Logging to the screen
screenMsg = screenMsg + text + "<br>";
$("#logMsgs").html(screenMsg);
} else {
// Logging to the browser console
console.log(text);
}
}
};

var handleException = function(e) {
consoleLog("EXCEPTION: " + e);
};

// *** Task 2 ***
var sliderChange = function(sliderValue) {
consoleLog("Slider changed: " + sliderValue);
};
// *** Task 2 ***
// Connecting…
//
var doConnect = function() {
// Connect to JMS, create a session and start it.
//
var jmsConnectionFactory = new JmsConnectionFactory(WEBSOCKET_URL);
try {
var connectionFuture = jmsConnectionFactory.createConnection(”, ”, function() {
if (!connectionFuture.exception) {
try {
connection = connectionFuture.getValue();
connection.setExceptionListener(handleException);

consoleLog("Connected to " + WEBSOCKET_URL);
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

// *** Task 3 ***
// Creating topic
var myTopic = session.createTopic(TOPIC_NAME);
consoleLog("Topic created…");
// *** Task 3 ***
// *** Task 4 ***
// Creating topic Producer
topicProducer = session.createProducer(myTopic);
consoleLog("Topic producer created…");
// *** Task 4 ***
connection.start(function() {
// Put any callback logic here.
//
consoleLog("JMS session created");
});
} catch (e) {
handleException(e);
}
} else {
handleException(connectionFuture.exception);
}
});
} catch (e) {
handleException(e);
}
};
[/sourcecode]

Run the modified app. Notice the log message indicating that the producer has been created.

[sourcecode language=”text” light=”true”]
Connected to wss://demos.kaazing.com/jms
Topic created…
Topic producer created…
JMS session created
[/sourcecode]

To see and run the updated code in JSFiddle, point your browser to the Task 4 state: https://jsfiddle.net/kaazing/0v6zhjsp/.

Task 5: Creating the consumer

To enable our application to receive messages, let’s create a consumer (or subscriber).

We will first create a consumer by invoking the createConsumer() function of the session object. We’ll also create a log entry about the successful creation of the consumer.

[sourcecode language=”javascript” light=”true”]
topicConsumer = session.createConsumer(myTopic);
consoleLog(‘Topic consumer created…’);
[/sourcecode]

Here’s the entire JavaScript file. Look for Task 5 in the comments to find the newly added function.

[sourcecode language=”javascript” collapse=”1″ highlight=”74,75,76″ wraplines=”false”]
// Variables you can change
//
var WEBSOCKET_URL = "wss://demos.kaazing.com/jms";
var TOPIC_NAME = "/topic/myTopic";
var IN_DEBUG_MODE = true;
var DEBUG_TO_SCREEN = true;

// WebSocket and JMS variables
//
var connection;
var session;
var wsUrl;

// Variable for log messages
//
var screenMsg = "";

// JSFiddle-specific variables
//
var runningOnJSFiddle = (window.location.hostname === "fiddle.jshell.net");

// Used for development and debugging. All logging can be turned
// off by modifying this function.
//
var consoleLog = function(text) {
if (IN_DEBUG_MODE) {
if (runningOnJSFiddle || DEBUG_TO_SCREEN) {
// Logging to the screen
screenMsg = screenMsg + text + "<br>";
$("#logMsgs").html(screenMsg);
} else {
// Logging to the browser console
console.log(text);
}
}
};

var handleException = function(e) {
consoleLog("EXCEPTION: " + e);
};

// *** Task 2 ***
var sliderChange = function(sliderValue) {
consoleLog("Slider changed: " + sliderValue);
};
// *** Task 2 ***
// Connecting…
//
var doConnect = function() {
// Connect to JMS, create a session and start it.
//
var jmsConnectionFactory = new JmsConnectionFactory(WEBSOCKET_URL);
try {
var connectionFuture = jmsConnectionFactory.createConnection(”, ”, function() {
if (!connectionFuture.exception) {
try {
connection = connectionFuture.getValue();
connection.setExceptionListener(handleException);

consoleLog("Connected to " + WEBSOCKET_URL);
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

// *** Task 3 ***
// Creating topic
var myTopic = session.createTopic(TOPIC_NAME);
consoleLog("Topic created…");
// *** Task 3 ***
// *** Task 4 ***
// Creating topic Producer
topicProducer = session.createProducer(myTopic);
consoleLog("Topic producer created…");
// *** Task 4 ***
// *** Task 5 ***
// Creating topic Consumer
topicConsumer = session.createConsumer(myTopic);
consoleLog("Topic consumer created…");
// *** Task 5 ***
connection.start(function() {
// Put any callback logic here.
//
consoleLog("JMS session created");
});
} catch (e) {
handleException(e);
}
} else {
handleException(connectionFuture.exception);
}
});
} catch (e) {
handleException(e);
}
};
[/sourcecode]

Run the modified app. Notice the log message indicating that the consumer has been created.

[sourcecode language=”text” light=”true”]
Connected to wss://demos.kaazing.com/jms
Topic created…
Topic producer created…
Topic consumer created…
JMS session created
[/sourcecode]

To see and run the updated code in JSFiddle, point your browser to the Task 5 state: https://jsfiddle.net/kaazing/5jth8h12/.

In Part 4, we’ll start sending and receiving messages to communicate across multiple browsers.