Search code examples
scalaakkaactor

TCP server handling multiple connections


I am trying to write a TCP server which handles multiple connections.

I know the way Java does it with sockets is that it has a pool of threads, the server has a while loop waiting for connections and when 'accpets' one it 'gets' a thread from the pool to handle the request. I was picturing something similar with actors.

class TcpServer(remote: InetSocketAddress) extends Actor {

  import Tcp._
  import context.system

  IO(Tcp) ! Bind(self, remote)

  def receive = {
    case b @ Bound(localAddress) =>
      context.parent ! b

    case CommandFailed(_: Bind) ⇒ context stop self

    case c @ Connected(remote, local) =>
      val handler: ActorRef =  context.actorOf(RoundRobinPool(5).props(Props[SimplisticHandler]), "router")
      sender() ! Register(handler)
  }

But obviously, that is not enough. What am i missing here?


Solution

  • For Akka TCP the pattern generally used is to have one actor handle the connection. Since actors get scheduled onto threads as needed by the ActorSystem's dispatcher, the pattern of getting a thread from a thread pool is provided more or less automatically by Akka (it's possible to, for instance, configure the default dispatcher to be a pool of a single thread, but that's not default and not recommended).

    With that in mind, you'll want to replace the

    context.actorOf(RoundRobinPool(5).props(Props[SimplisticHandler]), "router")
    

    with

    context.actorOf(Props[SimplisticHandler])
    

    and be sure in SimplisticHandler to

    context.stop.self
    

    in response to a ConnectionClosed message.