LoginSignup
3
2

More than 5 years have passed since last update.

Akka で TCP Echo Server

Posted at

前回はTCPクライアント側を書いたので次はサーバー側を.

要点

  • bindに成功したら Bound(localAddress) メッセージが来る
  • 新しい接続を accept したら Connected(remote, local) メッセージが来る
  • Connected後は sender()で接続主のアクターが取れる
  • 接続主のアクターに Registerメッセージを送って データのやり取りを行う Handler を登録する
  • データ受信すると HandlerReceived(data) メッセージが来る

受け取ったデータをそのまま返すだけのサーバー

EchoServer.scala
import java.net.InetSocketAddress

import akka.actor.{ActorSystem, Props, ActorLogging, Actor}
import akka.io.{IO, Tcp}

/**
 * 接続されたクライアントとデータのやり取りを行うHandler 
 */
class Handler extends Actor {
  import Tcp._

  def receive = {
    // 受け取ったデータをそのまま送信主に返す
    case Received(data) => sender() ! Write(data)
    case PeerClosed => context stop self
  }
}

/**
 * クライアントの接続を受け入れるサーバー
 */
class Server(bindAddress: InetSocketAddress) extends Actor with ActorLogging {
  import Tcp._
  import context.system

  IO(Tcp) ! Bind(self, bindAddress)

  def receive = {
    case Bound(localAddress) =>
      log.info("bound on {}...", localAddress)

    case Connected(remote, local) =>
      log.info("accepted peer: {}", remote)
      val handler = context.actorOf(Props[Handler])
      sender() ! Register(handler)

    case CommandFailed(_: Bind) =>
      log.error("bind failed")
      context stop self
  }
}

/**
 * メイン関数
 */
object EchoServer {
  def main(args: Array[String]): Unit = {
    val system = ActorSystem("MySystem")
    val bindAddress = new InetSocketAddress("localhost", 12345)
    system.actorOf(Props(classOf[Server], bindAddress))
  }
}
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2