TogetherJS
Want to add real-time collaboration to your Web application? Mozilla's TogetherJS is worth a look.
When Tim Berners-Lee invented the World Wide Web more than 20 years ago, he did it in the hopes that physicists would be able to collaborate easily with one another over the Internet. Since then, the Web has grown and morphed into a new medium that handles everything from newspapers to finance to supermarkets.
And yet, although we can marvel at the large number of things we can do on the Web nowadays, the original idea that drove it all, of collaboration, is still a bit of a dream. Sure, we have sites like GitHub, which provide a Web interface to the Git version-control system. And of course, we have plenty of writing systems, such as WordPress, that allow a number of people to create (and publish) documents. And there's also Facebook, which sometimes can be seen as collaborative.
But if you really think about it, we still don't have the sort of seamless collaboration we originally thought might be possible via the Web. Sure, I can work on something, hand it to others, and then work on it again when they are done with it, but it's still relatively rare to have collaborative tools on-line.
Perhaps the most sophisticated and widespread example of real-time, Web-based collaboration is Google Docs (now known, I think, as Google Drive). It's true that Google's applications make it possible for you to store your documents in the cloud, as people now like to say. And it's certainly convenient to be able to read and write your documents from anywhere, so long as you have access to a Web browser. But for me, the real power of Google Docs is in the collaboration. Many different people can work on the same document, and they even can do so at the same time. I found this sort of collaboration to be invaluable when I had to work with several other people to put together a budget on a project several years ago. The fact that we could all, from our own computers, edit the same spreadsheet in real time was quite useful.
There are a number of open-source alternatives to Google's word processor as well. Etherpad was released as an open-source project after its authors were acquired by Google several years ago. You can download and install Etherpad on your own, or you can take advantage of one of the existing Etherpad servers on-line. Another interesting application is Ace, a browser-based programming editor with impressive collaborative abilities.
Now, I never would claim that all collaboration needs to be in real time. There are many examples in the open-source world of people communicating and collaborating asynchronously, using e-mail and Git to work together—often quite effectively, without the bells and whistles that real-time collaboration seems to offer.
However, for many of us, collaboration without a real-time component is always missing something. It would be great for me not only to be able to talk to someone about a Web site, but also to look at it (and edit its content) along with them, in real time. Yes, there are screen-sharing systems, such as VNC, Join.me and ScreenHero, but they require that you install something on your computer and that you activate it.
That's why I have become interested in a project sponsored by the Mozilla Foundation known as TogetherJS. As the name implies, TogetherJS is a JavaScript-based, real-time collaboration system. The most impressive thing, in my opinion, is how much TogetherJS provides out of the box, with little or no configuration. It allows you to make your site more collaborative by adding some simple elements to each page.
So in this article, I want to look into TogetherJS—what it does, how you can add it to your own sites, and how you even can connect your application to it, creating your own, custom collaborative experience.
What Is TogetherJS?TogetherJS is a project sponsored by the Mozilla Foundation (best known for the Firefox browser and the Thunderbird e-mail client). Mozilla has been developing and releasing a growing number of interesting open-source tools during the past few years, of which TogetherJS is one of the most recent examples. (In recent months, for instance, Mozilla also released Persona, which attempts to let you sign in to multiple sites using a single identity, without tying it to a for-profit company.) TogetherJS was released by "Mozilla Labs", which, from the name and description, suggests this is where Mozilla experiments with new ideas and technologies.
On a technical level, TogetherJS is a client-server system. The client is a JavaScript library—or more accurately, a set of JavaScript libraries—loaded onto a Web page, which then communicates back to a server. The server to which things are sent, known in TogetherJS parlance as the "hub", runs under node.js, the JavaScript-powered server system that has become quite popular during the past few years. The hub acts as a simple switchboard operator, running WebSockets, a low-overhead protocol designed for real-time communication. Thus, if there are ten people using TogetherJS, divided into five pairs of collaborators, they can all be using the same hub, but the hub will make sure to pass messages solely to the appropriate collaborators.
Installing TogetherJS on a Web site is surprisingly easy. You first need to load the TogetherJS library into your page. This is done by adding the following line into your Web application:
<script src="https://togetherjs.com/togetherjs-min.js"></script>
Of course, you also can host the JavaScript file on your own server, either because you want to keep it private or internal, or if you are modifying it, or if you simply prefer not to have it upgrade each time Mozilla releases a new version.
That JavaScript file doesn't actually do much on its own. Rather, it checks to see whether you want to download a minimized version of the code. Based on that, it decides whether to download all of the code in a single file or in separate ones. Regardless of how you download TogetherJS, the above line ensures that the JavaScript component is ready to work.
But of course, it's not enough to install the JavaScript. Someone needs to activate and then use it, which means installing a button on your Web site that will do so. Once again, because of the way TogetherJS is constructed, it's pretty straightforward. You can install the following:
<button id="start-togetherjs" type="button"
onclick="TogetherJS(this);
↪return false">Start TogetherJS</button>
In other words, you create a button that, when clicked, invokes the TogetherJS function. When users click on that button, they will be added to TogetherJS. Now, this is actually pretty boring; if you're running TogetherJS by yourself, it's not going to seem to be doing very much. Once you click on the TogetherJS button, and after you click through the first-time introduction, you'll immediately be given a link, labeled "invite a friend". In my particular case, running this on port 8000 of my server, I get http://lerner.co.il:8000/togetherjs.html#&togetherjs=oTtEp6wmoF.
As you can see, the TogetherJS special-invitation URL combines the URL of the page you own, along with a token that uniquely identifies your session. This allows multiple sets of people to collaborate on the same page, with each set existing in its own, isolated environment.
For example, togetherjs.html (Listing 1) is a file that I put up on my server. I opened two separate browsers onto that page, one via the direct URL and the second by using the full URL shown above, with a specific confirmation token. Once both browsers were pointing to the site, and once both users had confirmed their interest in collaborating and using TogetherJS, I found that either user could modify the content of the "textarea" tag, and that no matter who was typing, the changes were reflected immediately on the other person's computer. In addition, each click of the mouse is displayed graphically. And if one user goes to a different page on the site (assuming that the TogetherJS library is on the other page as well), TogetherJS will ask the other user if he or she wants to follow along.
Listing 1. togetherjs.html
<!DOCTYPE html>
<html>
<head>
<h3>Collaborate!</h3>
</head>
<body>
<h1>Collaborate!</h1>
<textarea>Hello out there!</textarea>
<script src="https://togetherjs.com/togetherjs-min.js">
↪</script>
<div id="togetherjs-div">
<button id="start-togetherjs" type="button"
onclick="TogetherJS(this); return false"
data-end-togetherjs-html="End TogetherJS">Start
↪TogetherJS</button>
</div>
</body>
</html>
Configuration and Customization
It's great and amazing that TogetherJS works so well, immediately upon installing it. However, there also are ways you can configure TogetherJS, so it'll reflect your needs. Because of the way TogetherJS is loaded, it's recommended that you make these configuration settings before TogetherJS has been loaded. For example:
<script>
var TogetherJSConfig_siteName = "Reuven's page";
</script>
<script src="https://togetherjs.com/togetherjs-min.js">
All of the configuration variables begin with
TogetherJSConfig_
and
have names that are fairly descriptive. A full list is on the
TogetherJS site at
https://togetherjs.com/docs/#configuring-togetherjs, but you also
can look through the together.js code, which contains comments describing
what the configuration variables do.
For example, if you decide you want to run your own hub (that is, a
message-passing, WebSockets-based server), you must tell
TogetherJS to look in a different location, with
TogetherJSConfig_hubBase
.
Other useful configuration variables are:
-
TogetherJSConfig_useMinimizedCode
: downloads the minimized JavaScript files for the rest of TogetherJS. -
TogetherJSConfig_inviteFromRoom
: allows you to think about collaboration on a site-wide basis. -
TogetherJSConfig_youtube
: when set, this means that if one person views a YouTube video, everyone will, and they will be synchronized.
But, TogetherJS provides more than just the ability to configure and use it. You also can extend it. The same message-passing system that TogetherJS uses for itself is available to developers. Thus, you can send arbitrary messages, for arbitrary events, between all of the people currently collaborating on this system.
In order to send an arbitrary JSON message, all of the parties involved need to agree on the message "type"—that is, the string that you will use to identify your message. All parties also need to register their interest in receiving messages of this type and to define a callback function that will fire when the message is sent. Although it makes sense to do this within the HTML or JavaScript in your application, it's also possible to do it in your favorite browser's JavaScript console.
First, you register interest in your object by telling TogetherJS that
whenever it receives a message of a certain type from a hub (using the
TogetherJS.hub.on
methods), it should fire a particular callback:
TogetherJS.hub.on("reuvenTest",
function (msg) {
console.log("message received: " + msg)
}
);
Now, it's true that because your message is an object, it will be printed as "[Object object]" in the Web console, which is really too bad. If you prefer, you can choose individual fields from the object, but be sure that you know what fields you will be receiving.
To send a message, just invoke TogetherJS.send
along with a JSON
object that will be sent to all of the other TogetherJS subscribers on
this channel. There is no way to send a message to one particular
computer; in this way, the paradigm is similar to what you probably saw with
real-time Web updates with Pusher and PubNub last year.
To send a message, you use the following:
TogetherJS.send({type: "reuvenTest", foo:
↪'foofoo', bar: 'barbar'});
I should note that both of these methods return undefined to the caller. Normally, this isn't a problem, but if you're working in the console, you might not expect such a response.
Of course, the power of this communication channel is in deciding what you want to communicate, and what should happen when communication comes in. When a message arrives, do you want to change the way something is displayed on the receivers' screens? Do you want to display a message for the user?
ConclusionTogetherJS is relatively new, and I am still in the early stages of using it in my applications that require real-time collaboration. That said, TogetherJS is an interesting application in and of itself, and it was designed as a platform that will continue to grow and expand. With TogetherJS, we are one additional step closer to using the Web for new and different forms of collaboration.
ResourcesThe home page for TogetherJS is http://togetherjs.com, but the GitHub page is https://github.com/mozilla/togetherjs. You can use TogetherJS with any modern browser, which basically means that it does not support Internet Explorer. I was able to get it to work with Firefox, Chrome and Safari (on OS X) without any problems. Note: TogetherJS explicitly states that it doesn't support Internet Explorer very well, including the most recent versions, which means that if you're working in a mixed environment, it might not be a good choice.