Akka 2.0 provides a clean
mechanism for non blocking I/O, abstracting all the details of NIO.
The example provided is very detailed but a little large to serve as an introduction.
The code below implements a very simple network service: read a length delimited ascii string and print it. The length is a 4 digit human readable number, for ease of testing.
The code can then exercised using
netcat
nc localhost 9999 <
val socket = server.accept()
state(socket) flatMap (_ => LengthBoundedServer.printMessage)
case Read(socket, bytes) =>
state(socket)(Chunk(bytes))
case Closed(socket, cause) =>
state(socket)(EOF(None))
state -= socket
}
}
object LengthBoundedServer {
import IO._
def ascii(bytes: ByteString): String = bytes.decodeString("US-ASCII").trim
def printMessage: IO.Iteratee[Unit] =
repeat {
for {
string <- readMessage
} yield {
println(string)
}
}
def readMessage: IO.Iteratee[String] =
for {
lengthBytes <- take(4)
len = ascii(lengthBytes).toInt
bytes <- take(len)
} yield {
ascii(bytes)
}
}
object Main extends App {
val port = Option(System.getenv("PORT")) map (_.toInt) getOrElse 9999
val system = ActorSystem()
val server = system.actorOf(Props(new LengthBoundedServer(port)))
}