Skip to content

Instantly share code, notes, and snippets.

@rossabaker
Forked from casualjim/boot.scala
Created December 14, 2010 21:05
Show Gist options
  • Save rossabaker/741097 to your computer and use it in GitHub Desktop.
Save rossabaker/741097 to your computer and use it in GitHub Desktop.
package com.mojolly.websocket
import akka.actor.{Scheduler, Actor}
import java.util.concurrent.TimeUnit
import Actor._
import org.jredis.ri.alphazero.JRedisClient
/*
* Gets executed by the listener defined in web.xml
*/
case class RegisterCallback(cb: String => Unit)
case object Poll
class PollerActor extends Actor {
val redis = new JRedisClient("localhost", 6379)
private var _callback: Option[String => Unit] = None
protected def receive = {
case Poll => _callback foreach { cb =>
val msg = Option(redis.lpop("message_queue"))
msg foreach { bytes =>
cb(new String(bytes, "UTF-8"))
}
}
case RegisterCallback(cb) => _callback = Some(cb)
}
}
class Boot {
val poller = actorOf[PollerActor].start
Scheduler.schedule(poller, Poll, 500, 500, TimeUnit.MILLISECONDS)
}
package com.mojolly.websocket
import org.eclipse.jetty.server.Server
import javax.servlet.http.{HttpServlet, HttpServletResponse, HttpServletRequest}
import org.eclipse.jetty.continuation.ContinuationSupport
import java.lang.String
import org.eclipse.jetty.webapp.WebAppContext
import akka.actor.ActorRegistry
class CometServlet extends HttpServlet {
override protected def doGet(req: HttpServletRequest, resp: HttpServletResponse) {
println("Got request for continuation")
val cont = ContinuationSupport.getContinuation(req)
cont.setTimeout(5000)
println(cont.toString)
if (cont.isInitial) {
cont.getServletResponse.getWriter.println("hello...")
cont.getServletResponse.flushBuffer
ActorRegistry.actorsFor(classOf[PollerActor]) foreach { _ ! RegisterCallback(
msg => {
cont.getServletResponse.getWriter.println(cont.getAttribute("messages").toString)
cont.getServletResponse.flushBuffer
cont.complete()
}
)}
}
cont.suspend()
}
}
object WebServer {
def main(args: Array[String]) {
val server = new Server(8888)
val context = new WebAppContext
context.setDescriptor("src/main/webapp/WEB-INF/web.xml")
context.setResourceBase("src/main/webapp")
context.setContextPath("/")
context.setParentLoaderPriority(true)
server.setHandler(context)
server.start
server.join
}
}
<?xml version="1.0"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="Backchat Streams"
version="2.5">
<listener>
<listener-class>akka.servlet.Initializer</listener-class>
</listener>
<servlet>
<servlet-name>StreamServlet</servlet-name>
<servlet-class>com.mojolly.websocket.CometServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StreamServlet</servlet-name>
<url-pattern>/stream</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/images/*</url-pattern>
<url-pattern>/css/*</url-pattern>
<url-pattern>/js/*</url-pattern>
</servlet-mapping>
</web-app>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment