Richard Searle's Blog

Thoughts about software

SImpler akka io example

Posted by eggsearle on February 23, 2012

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 <<!
0001A0002XY
!

import akka.actor._
import akka.util.{ ByteString, ByteStringBuilder }
import java.net.InetSocketAddress

class LengthBoundedServer(port: Int) extends Actor {
  import IO._

  val state = IterateeRef.Map.async[IO.Handle]()(context.dispatcher)

  override def preStart {
    IOManager(context.system) listen new InetSocketAddress(port)
  }

  def receive = {

    case NewClient(server) =>
      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)))
}
Advertisements

5 Responses to “SImpler akka io example”

  1. Derek Williams said

    Thanks for the feedback! I need to finish that documentation, including adding a simpler example app. The http server seemed simple at first, but it turned out writing the code was much easier then explaining the code.

    Your example here is the first I’ve seen using Akka’s IO other then my own, looks easier to follow then most of them too.

    • eggsearle said

      The comments on the http server were quite clear. Understanding the iteratees was more difficult.

      The code that references IO (e.g. IO peek 1 flatMap {…}) was not immediately obvious. The key point is that this code is actually building a function.

  2. […] the code from https://cognitiveentity.wordpress.com/2012/03/10/akka-system-io-client/ and https://cognitiveentity.wordpress.com/2012/02/23/simpler-akka-io-example/ to send data serialized using […]

  3. shawn said

    I’m not clear on the relationship between the class LengthBoundedServer and the object LengthBoundedServer. Is the latter an instance of the former?

    • shawn said

      Ah nevermind, I was unaware of the “companion object” pattern / feature of scala. Please disregard.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: