I saw the Akka module’s description says that Play has great Comet support, but I’ve never used Comet before and I can’t find any mention of it in Play’s documentation. How does it work in Play?
I spent a few hours over two days figuring this out so I wanted to share this info for other Play beginners.
Play includes a sample Chat application which demonstrates how to use Comet. The example doesn’t explain what’s going on though, so here’s what I’ve figured out.
Model
In order for others to find new updates you send, they’ll need to be stored somewhere. Conceivably this could be in a cache or even in the controller itself, but the database is going to be the safest bet, so you’ll want a model. They’ll also need a way to determine which updates are new to them, which means you’ll probably want a date field (see also: Last update timestamp with JPA). The Chat example uses a simple model:
Controller
The controller needs two methods to facilitate Comet. One where new data is posted, which doesn’t do anything special:
and one for retrieving updates:
The key bit here is
suspend("1s")which is what holds the HTTP request open, checking for new data once per second.View
The view has three responsibilities — sending new data, fetching updates and then rendering those updates.
Sending, like the corresponding controller action, doesn’t do anything special:
Fetching updates is the magic bit:
getMessages()is called once to get things started, and afterwards it calls itself recursively after each successful request. It GETs thenewMessages()action which looks for new messages, and if there aren’t any it holds the request open until it has something to report. When new messages are found, the JSON data is passed to adisplayfunction:The
displayfunction applies a JavaScript Micro-Template to the JSON data to render new messages. Use of micro templates isn’t necessary, but it does work pretty well. They’re included right in the template of the page that’s going to use them:The
type="text/html"causes browsers, search engines and screen readers to ignore the wholescriptblock. The result is much easier to read and maintain than using jQuery to build nodes or concatenating strings. Overall it’s pretty simple once you know which bits are relevant.