Lift Comet Chat Example
I recently did a presentation on Lift. A lot of the materials were drawn from:David Pollak’s Java One Presentation and Marius Danciu’s Presentation. I posted the slides at linkedin. I wanted to demostrated Lift’s strength. So I created a quick Comet Chat example based on David’s code.
There were quite a few requests on the code. Instead of just create a zip file to let you download it. I’m going to walk you through how to build it.
First you need maven2. You can’t do anything with lift without it. You can download it here Come back to this when you finish downloading and installing it. You need to be able to issue mvn command.
Next we are going to create the lift project. For this one, we’ll use the lift-archetype-blank archetype.
mvn archetype:generate -U \ -DarchetypeGroupId=net.liftweb \ -DarchetypeArtifactId=lift-archetype-blank \ -DarchetypeVersion=1.0 \ -DremoteRepositories=http://scala-tools.org/repo-releases \ -DgroupId=demo.app \ -DartifactId=chat \ -Dversion=1.0-SNAPSHOT
After tons of maven stuff scrolling through your screen. When it’s done. A directory called chat will be created. Now let’s run it to make sure it works.
cd chat mvn jetty:run
If this part worked. You’ll see jetty up and running at port 8080. You can check it out by going to http://localhost:8080 on your browser.
Hit Ctrl-C and stop the running jetty. Onward to the next part.
Now you need to create src/main/scala/demo/app/comet/Chat.scala
package demo.app.comet
import scala.actors.Actor
import Actor._
import net.liftweb._
import http._
import js._
import SHtml._
import JsCmds._
case class Messages(msgs: List[String])
object ChatServer extends Actor with ListenerManager {
private var msgs: List[String] = Nil
protected def createUpdate = Messages(msgs)
override def highPriority = {
case s: String if s.length > 0 =>
msgs ::= s
updateListeners()
}
this.start
}
class Chat extends CometActor with CometListenee
{
private var msgs: List[String] = Nil
def render =
{
msgs.reverse.map( m =>
- {m}
)
}
{
ajaxText("", s => {ChatServer ! s; Noop})
}
protected def registerWith = ChatServer
override def highPriority = {
case Messages(m) =>
msgs = m ;
reRender(false)
}
}
That takes care of the code. You now have to include it in the view. To do this, edit src/main/webapp/index.html
The default file looks like below
<lift :surround with="default" at="content">
<h2>Welcome to your project!</h2>
<p><lift:helloWorld.howdy /></p>
</lift:surround>
Replace it with
<lift :surround with="default" at="content">
<lift:comet type="Chat" />
</lift:surround>
That’s it. Now issue
mvn jetty:run
And you’ll see the Comet Chat in all its glory.


At first I did not get your example to work. The problem I found was that the view code did not invoke comet correctly and did not close the tags correctly. This works:
That comment did not include the code. Here is a gist of it
http://gist.github.com/169681
Thanks for the catch, the syntax highlighting js messed it up. I put in
the js stripped and realigned stuff on the fly. I removed the call to the js. It looks right now. It’s ironic often posting code to the web is one of the hardest.
Sorry about that. I should’ve noticed. Because it messed up the default index.html generated by lift too.
compile error:
type mismatch;
[WARNING] found : List[String]
[WARNING] required: net.liftweb.http.RenderOut
[WARNING] msgs.reverse.map( m => {m})
[WARNING]
sorry for the previous message. The syntax highlighter hide some code and I mis copied.
no problem, glad you find this useful.