A lightweight clean implementation of the Bayeux (COMET) protocol as a jQuery plugin, with a test server in Sinatra (uses async_sinatra under Thin).
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"> </script> <script src="jquery.comet.js"> </script> <script> // Connect and start polling: $.comet.connect('http://my.server.com:9191/cometd') // Receive messages sent to this channel: $.comet.subscribe('/myapp/channel1', function(msg) { ... }); // Send a message via the server to all subscribers on this channel: $.comet.publish('/myapp/channel1', {some: obj, json: 2}); // Stop listening to channel: $.comet.unsubscribe('/myapp/channel1'); // Stop polling $.comet.disconnect(); </script>
When you publish a message, it won’t get sent immediately. You can publish as many as you like within the one function, and even return to where other queued callbacks will publish additional messages, and your messages will be batched and sent all together when the browser pauses.
If a poll fails, messages will be queued until it comes back again. Once a message has been sent however, there’s no guarantee it will be delivered in the case of a server crash.
You need to have Ruby installed. Then:
gem install thin async_sinatra rack bayeux-rack cd chat_server rackup --server thin
Now visit localhost:8080 with one or more browsers. Because it uses async_sinatra, which uses EventMachine, it won’t work in Passenger. Sorry about that, but Apache doesn’t really like long-polling anyhow.
The jquery.comet.js and chat_server are subject to the MIT license.
The client_demo directory contains a chat client written by Morgan Allen, and subject to the GPL v2. See his original code at <code.google.com/p/jquerycomet/>.
Tested on Chrome, Safari, and FF3.5.
JSONP (cross-domain) support requires jQuery >= 1.5.0
Fork on github <github.com/cjheath/jquery.comet> or just clone to play:
git clone git://github.com/cjheath/jquery.comet.git
Patches welcome! Fork and send a pull request. Please follow coding conventions already in use. Please use jslint if you can. There are currently no warnings, please keep it that way.
Current release has a happy path (working ok), but other paths are less well tested:
-
Callback polling
-
Cross-domain polling using JSONP
-
Renegotiating the handshake
Some enhancements are on the cards:
-
Multiple subscriptions to the same channel
-
Wildcard subscriptions (/channel/*/foo, /channel/**, etc)