Writing Comet Applications Using Scala and the Atmosphere Framework

DZone 's Guide to

Writing Comet Applications Using Scala and the Atmosphere Framework

· Java Zone ·
Free Resource

Writing Atmosphere's Comet based applications is simple. Imagine using Scala instead of Java...it becomes really simple! No need to learn Lift anymore :-)

Not being an expert with Scala at all, I've decided to re-wrote the Chat based application I've recently used when adding cluster support to Atmosphere. This is really my first ever Scala application so don't jump looking at the code! Instead, tweet me a better implementation. I will not go into the details of how to write an Atmosphere application, so if this is the first time you learn about Atmosphere, start here.

For the chat, I've needed to implement two methods: one that will be invoked when suspending a response (Comet's HTTP streaming technique), and one for sending chat messages to those suspended response (to the other chat member). To do that in Scala, I did:

  package org.atmosphere.samples.scala.chat

import javax.ws.rs.{GET, POST, Path, Produces, WebApplicationException, Consumes}
import javax.ws.rs.core.MultivaluedMap
import org.atmosphere.core.annotation.{Broadcast, BroadcastFilter, Suspend}
import org.atmosphere.util.XSSHtmlFilter

class Chat {

var JUNK : String = "<!-- Comet is a programming technique that enables web " +
"servers to send data to the client without having any need " +
"for the client to request it. -->\n"

def suspend() = {
var s = new StringBuilder()
for (i <- 0 to 10){

def publishMessage(form: MultivaluedMap[String, String]) = {
val action = form.getFirst("action")
val name = form.getFirst("name")

val result: String = if ("login".equals(action)) "System Message" + "__" + name + " has joined."
else if ("post".equals(action)) name + "__" + form.getFirst("message")
else throw new WebApplicationException(422)


To suspend the response, I've annotated the suspend() method (line 15) with @Suspend. The returned value of the suspend() method will be written and then the response will be suspended, waiting for server event, e.g messages from other chatter. Now when someone publish a message, method publishMessage() will be invoked. Since the method is annotated with @Broadcast (line 26), the method's returned value will be broadcaster to all suspended response, e.g. all suspended connections will get a chance to write the message. But since I don't want users to publish script or any kind of attack, I've also added the @BroadcastFilter annotation, which will make sure to filter malicious characters. Since my javascript client expect JSONp response, I've decided to write a BroadcastFilter in Scala that transform the message:

  package org.atmosphere.samples.scala.chat

import org.atmosphere.cpr.BroadcastFilter

class JsonpFilter extends BroadcastFilter[String] {

val BEGIN_SCRIPT_TAG = "<script type='text/javascript'>\n"
val END_SCRIPT_TAG = "</script>\n"

def filter(m : String) = {
var name = m
var message = ""

if (m.indexOf("__") > 0) {
name = m.substring(0, m.indexOf("__"))
message = m.substring(m.indexOf("__") + 2)

val result: String = (BEGIN_SCRIPT_TAG + "window.parent.app.update({ name: \""
+ name + "\", message: \""
+ message + "\" });\n"

Then I just pass the name of that class to the @BroadcastFilter annotation:


What amaze me here is one filter is written in Java, the other one in Scala!. That's it. With those two classes, the Atmosphere REST Chat demo works. To complicate the application, I've decided to deploy it into a cluster. This is simple to achieve by annotating the publishMesaage with:


Now my Scala application is Comet-Cluster enabled! That was fun!

For any questions or to download the above sample, go to our main site and use our Nabble forum (no subscription needed) or follow us on Twitter and tweet your questions there!


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}