Skip to content

Instantly share code, notes, and snippets.

@bssstudio
Created January 11, 2013 07:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bssstudio/4508743 to your computer and use it in GitHub Desktop.
Save bssstudio/4508743 to your computer and use it in GitHub Desktop.
Dead simple http responder (not even echo test)
//scalaVersion 2.9.2
//akkaVersion 2.0.1
import akka.actor._
import java.net.InetSocketAddress
import akka.util.ByteString
import java.net.Socket
import akka.actor.IO.SocketHandle
import akka.actor.IO._
import akka.routing.RoundRobinRouter
import akka.util.ByteStringBuilder
case class SimpleMsg(val line: ByteString, val socket: IO.SocketHandle)
class LineProc extends Actor {
def ascii(bytes: ByteString): String = bytes.decodeString("US-ASCII").trim
def receive = {
case line: ByteString => {
//println(ascii(line))
}
case msg: SimpleMsg => {
//println(Thread.currentThread().getName()+" - "+ ascii(msg.line))
//msg.socket.write(msg.line)
//msg.socket.close()
//val builder = ByteString.newBuilder
//builder.+()
//builder.
//val bytestr = builder.result
//for (i <- 1 to 1000000) {
// i + 1
//}
val bytestr = ByteString("HTTP/1.1 200 OK\r\nContent-Length: 0\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n")
//println(bytestr)
msg.socket write( bytestr )
msg.socket close
}
}
}
class TCPServer(port: Int) extends Actor {
val state = IO.IterateeRef.Map.async[IO.Handle]()(context.dispatcher)
val processor = context.actorOf(Props[LineProc].withRouter(RoundRobinRouter(1000)))
override def preStart {
IOManager(context.system) listen new InetSocketAddress(port)
}
def receive = {
case IO.NewClient(server) => {
val client = server.accept()
//println("New client "+ client)
state(client) flatMap (_ ⇒ HttpServer.processRequest(client,processor))
}
/*
case IO.Read(rHandle, bytes) => {
rHandle.asSocket write bytes.compact
rHandle.asSocket write ByteString("started longly task")
Thread.sleep(30000)
rHandle.asSocket write ByteString("done")
}
*/
case IO.Read(socket, bytes) ⇒ {
state(socket)(IO Chunk bytes)
}
case IO.Closed(socket, cause) ⇒ {
//state(socket)(IO.)
state -= socket
}
}
}
object HttpServer {
def processRequest(socket: IO.SocketHandle, processor: ActorRef): IO.Iteratee[Unit] =
IO repeat {
for {
line <- takeUntil(ByteString("\r\n"),false)
line2 <- takeUntil(ByteString("\r\n"),false)
line3 <- takeUntil(ByteString("\r\n"),false)
line4 <- takeUntil(ByteString("\r\n"),false)
//line5 <- takeUntil(ByteString("\r\n"),false)
line6 <- takeUntil(ByteString("\r\n"),false)
//line <- take(1)
} yield {
//println(line)
processor ! line
processor ! line2
processor ! line3
processor ! line4
//processor ! line5
processor ! new SimpleMsg(line6,socket)
}
}
}
object TCPServer extends App {
val port = Option(System.getenv("PORT")) map (_.toInt) getOrElse 8080
ActorSystem().actorOf(Props(new TCPServer(port)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment