TIBCO PageBus™ is a JavaScript library that can help you make your JavaScript code more modular and easier to maintain and extend.

Let's take a contrived example, where you have a button on the page, and you want a number of things to occur when that button is clicked:

  • Update a counter with the number of clicks
  • Update a counter with the number of clicks per minute
  • Update a Chart of the clicks and clicks per minute over time

This is fairly easy to achieve without PageBus as shown in the the following example:

The main piece of JavaScript looks as follows:

var clickStats = {
 start: new Date(),
 count: 0,
 duration : 0,
 addClick: function() {
 	this.duration = new Date() - this.start;
 	++this.count;
 	updateCounter( this );
 	updateCounterPM( this );
 	updateChart( this );
 },
 clicksPM : function() {
 	return Math.round((this.count/(this.duration/1000.0/60.0))*100.0) / 100.0;
 },
}

and the button looks like:

<button onclick="clickStats.addClick();">Click Me</button>

When you click on the button, clickStats.addClick() is called, which updates the statistics, the counters and the chart. Nothing unusual going on here.

Now lets look at the same example using TIBCO PageBus™ as shown in the the following example:

The main piece of JavaScript looks as follows:

var STATS_SUBJECT = "Stats.Clicks";
var BUTTON_SUBJECT = "Button.Clicked";

var clickStats = {
	start: new Date(),
	count: 0,
	duration : 0,
	addClick: function() {
		this.duration = new Date() - this.start;
		++this.count;
		PageBus.publish( STATS_SUBJECT, this );
	},
	clicksPM : function() {
		return Math.round((this.count/(this.duration/1000.0/60.0))*100.0) / 100.0;
	},
}
PageBus.subscribe( BUTTON_SUBJECT, clickStats, clickStats.addClick);

and the button looks like:

<button onclick="PageBus.publish( BUTTON_SUBJECT );">Click Me</button>

When you click on the button, an message is published on the PageBus using the subject "Button.Clicked". This results in clickStats.addClick() being called as it's subscribed to that subject. clickStats.addClick() updates the click statistics and publishes a message on the subject "Stats.Clicks". Functions for the counters and chart are subscribed to that subject and are subsequently called and the counters and charts are updated.

So what makes the version with PageBus better?

First lets, compare the button elements. In the version without PageBus, the button directly calls clickStats.addClick(), which is a tight coupling. If you decide to change the name of clickStats.addClick() or the way it's called, then you will need to change the button and any where else where you call clickStats.addClick(). For a complex web app, such a change could require updating any number of files. In the version with PageBus, you only need to update the subscription, which is located with the definition of clickStats.

Next compare the clickStats object. In the version without PageBus, addClick() needs to know all the components that need to be updated when the statistics are updated. Adding or removing any of these components from the page means you need to update clickStats.addClick(). In the version with PageBus, components can be added or removed and you only need to worry about the subscriptions of the components you are adding or removing. For example, just say you want to add code to use FireBug to log clickStats whenever it's updated. In the PageBus example, you don't need to modify clickStats at all, you can just add the following code

function statsLogger( subject, stats, data ) {
	if( console != undefined && console.log != undefined ) {
		console.log( stats );
	}
}
PageBus.subscribe( "Stats.**", null, statsLogger );

Now when you click on the button, the updated stats are logged to the console.

Subject Wild Cards

In the subscription for the logger, the subject "Stats.**" is used instead of "Stats.Clicks". "**" is a wild card, so "Stats.**" matches any subject beginning with "Stats.". What this means is that you can add other types of statistics objects (e.g., for tracking the number of AJAX requests) and so long as you make it a standard that all statistics object publish on the subject "Stats.category", then your logger will automatically log them as well. Handy eh?

Want More?

PageBus integrates directly with the yet to be released TIBCO Ajax Message Service™ (TAMS). TAMS provides a wrapper for the XMLHttpRequest Object and a implementation of reverse AJAX (A.K.A Comet). The details of how they are implementing reverse AJAX are not available yet, but no doubt it's based on DWR which TIBCO has been sponsoring.

What this means is that you could change the example above to subscribe to "Stats.Hits", use TIBCO Ajax Message Service™ to publish a message whenever the server renders particular pages and all of a sudden your modified example can now chart live hits on your site. I'm sure there are more details, but we won't know what they are until TAMS is released.

Conclusion

TIBCO PageBus™ provides you with a JavaScript messaging library within your web application that allows you to reduce tight coupling between components. Having a loose coupling makes your code easier to change, easier to maintain and easier to extend.

Downloads