前回はTCPクライアント側を書いたので次はサーバー側を.
要点
-
bind
に成功したらBound(localAddress)
メッセージが来る - 新しい接続を
accept
したらConnected(remote, local)
メッセージが来る -
Connected
後はsender()
で接続主のアクターが取れる - 接続主のアクターに
Register
メッセージを送って データのやり取りを行うHandler
を登録する - データ受信すると
Handler
にReceived(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))
}
}