0

Akka では、IOManager は「IO を実行するためのソケットを作成するための推奨されるエントリ ポイントです」。API を見ていて、読み取りタイムアウトを設定する方法を知りたいですか? もちろん、アクターが n 秒以内にメッセージを発行してソケットを閉じるようにスケジュールすることもできますが、アクターはその時間内にすべての読み取りを既に受信しており、現在、読み取りデータの処理に取り組んでいる可能性があります。したがって、これは読み取りタイムアウトではありません。これを行う方法はありますか?それとも、何らかの方法でアクターに状態を導入する必要がありますか?

4

1 に答える 1

1

わかりました、Derek Williams が akka-user についてヒントをくれました。他の誰かが同様のことをする必要がある場合に備えて、コードを次に示します。

新しいクライアントを受け入れると、タイマーを 5 秒に設定して接続を閉じます。

def receive = {
  case IO.NewClient(server) =>
    val socket = server.accept()
    val readTimeout = context.system.scheduler.scheduleOnce(5 seconds, self, Timeout(socket))
    state(socket) flatMap (_ => MyServer.processRequest(socket, readTimeout))

  case IO.Read(socket, bytes) =>
    state(socket)(IO Chunk bytes)

  case IO.Closed(socket, cause) =>
    state(socket)(IO EOF None)
    state -= socket

  case Timeout(socket) =>
    socket.close()
}

読み取り後にタイムアウトをキャンセルするには、Cancellable スケジュールで cancel() を呼び出します。

object MyServer {
  def processRequest(socket: IO.SocketHandle, readTimeout: Cancellable): IO.Iteratee[Unit] =
    for {
      request <- readRequest
    } yield {
      readTimeout.cancel()

      request match {
          val response = ...
          socket write ByteString(response).compact
          socket.close()
      }
    }
}
于 2012-04-18T15:36:08.253 に答える