This tutorial will describe how to set up an introductory “real time chat” application using the Orbited framework and TurboGears. Real-time web-sites are capable of far more than simple chat applications, but chat is the common “Hello World” of real-time developers.
Warning
You should already be fairly familiar with TurboGears, Javascript and JQuery before you begin this tutorial.
Note
The setup described here is not a production-ready real-time-web solution. MorbidQ is not a production Message Queue Server, and indeed most production solutions would want to use a more robust and efficient protocol such as AMQP. Currently AMQP protocols for Javascript are “in development”. This document is intended to let you get started with real-time-web development before you graduate to more mature technologies.
You will need to have a running TurboGears VirtualEnv to follow along in this tutorial. We recommend the TurboGears 2.1.5 Standard Installation if possible.
Orbited provides a “web socket” mechanism that allows Javascript code to connect to (defined) servers to recieve messages. The networking protocol spoken by the Javascript code can be any implemented TCP protocol. The following are the protocols commonly used with Orbited:
Orbited’s model means that with a simple Javascript plugin which speaks a given protocol, your Javascript code can be connected to any server and port on the Internet (with the proper Orbited configuration).
To install the Orbited framework in your VirtualEnv we need to install the Orbited 0.7.10+ and Twisted 9.0+ packages. This will also pull in the morbidq package.
(tgenv)$ easy_install twisted orbited
MorbidQ provides an easily configured message broker/queue which is not intended for large-scale production use. It uses the simple STOMP protocol. If you want to stick with STOMP as you scale up, you can explore the other STOMP servers available.
Note
There are (far) faster message queue engines than Morbid, but most of them use the AMQP binary protocol. There is an experimental AMQP implementation for Javascript available in Kamaloka-js. It is suggested that you become comfortable with real-time-web programming before switching to a full-featured Queue server.
To configure MorbidQ and Orbited, you need a config file. Something like the following, which we will save as “chat.ini” in our “rtchat” project’s directory.
[listen]
# this is the server which provides the socket-proxy for javascript
http://:9000
# the following enables the MorbidQ STOMP Message Queue
stomp://:61613
[access]
# allow incoming HTTP requests on port 9000 to connect to
# localhost:61613 (i.e. the MorbidQ STOMP server)
# The * refers to the
* -> localhost:61613
[global]
session.ping_interval = 20
You can now run Orbited with the embedded MorbidQ queue with the following command:
(tg2env)$ orbited --config=chat.ini
You should see messages telling you that Orbited/MorbidQ is listening on the defined ports. You can hit CTRL-C to stop the server, though we’ll want to use it in a moment, so you’ll likely want to leave it running and start another console.
We are going to be very simplistic with our chat widget in our first attempt. We’ll simply dump the text which is sent to the server into a div node. The view looks like this:
<?python
# we pull some values out of TurboGears config-file, with defaults
# for our tutorial settings.
from simplejson import dumps as d
orbited_server = config.get( 'orbited_server', 'localhost' )
orbited_port = config.get( 'orbited_port', 9000 )
stomp_server = config.get( 'stomp_server', 'localhost' )
stomp_port = config.get( 'stomp_port', 61613 )
orbited_files = 'http://%s:%s/static'%( orbited_server, orbited_port )
?>
<div id="chat">
<h2>Real-time Chat</h2>
<div class="chat-trace">
</div>
<div class="chat-entry">
Chat:
<input class="chatter" />
<button class="chat-trigger">Send</button>
</div>
</div>
We are going to use JQuery for our javascript framework. Here we use the Google javascript APIs version of the library:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
The JSON javascript library provides for safe JSON parsing, that is, it actually parses the JSON data rather than doing an unsafe “eval” on the code. We linked it into our “public” directory above.
<script type="text/javascript" src="${orbited_files}/JSON.js"></script>
The Orbited javascript library implements the “proxied socket” mechanism which connects to the Orbited server we started above. We’ll use Orbited’s proxy-socket to connect to the MorbidQ server via STOMP. We configure the Orbited client before we import the STOMP client library as the STOMP client library references “TCPSocket” as seen here.
<script type="text/javascript" src="${orbited_files}/Orbited.js"></script>
<script type="text/javascript">
// This line is required to allow our chat server and this
// page to operate on different ports...
document.domain = document.domain;
// Establish the port and server for the Orbited server
Orbited.settings.port = 9000;
Orbited.settings.hostname = ${simplejson.dumps( chat_server )};
// Enable streaming operation
Orbited.settings.streaming = true;
// This object is referenced by stomp.js
TCPSocket = Orbited.TCPSocket;
</script>
<script type="text/javascript" src="${orbited_files}/protocols/stomp/stomp.js"></script>
The chat client we show here is extremely simplistic. It is intended to show you the minimum required to get messages flowing across the MorbidQ server.
<script type="text/javascript">
var add_message = function( text ) {
var node = $('<div class="chat-message"></div>');
node.append( text );
$('.chat-trace').append( node );
};
$(document).ready( function() {
stomp = new STOMPClient();
stomp.onconnectedframe = function(frame) {
stomp.subscribe( "/topic/chat" );
};
stomp.onmessageframe = function( frame ) {
add_message( frame.body );
};
stomp.connect(${d(stomp_server)},${d(stomp_port)} );
$('.chat-entry .chat-trigger').click( function() {
var chatter = $('.chat-entry .chatter');
var value = chatter.attr( 'value' );
if (value.length) {
stomp.send( value, "/topic/chat" );
chatter.attr( 'value', '' );
}
});
});
</script>
You should now be able to start your TurboGears server, browse to http://localhost:8080 and start chatting. Your messages should show up in the chat-trace DIV as you enter them.
You will immediately notice problems with the chat system, some obvious enhancements:
There are a number of callbacks of the STOMP object that you may wish to override to perform basic configuration and the like:
The methods to control the STOMP object are: