読者です 読者をやめる 読者になる 読者になる

Java7からのNIO2で高凝縮のエコーサーバを書いてみた


単なるエコーサーバをScalaで凝縮してみると、、

import java.net.{InetSocketAddress, StandardSocketOptions}
import java.nio.ByteBuffer
import java.nio.channels.{AsynchronousSocketChannel, CompletionHandler, AsynchronousServerSocketChannel}

object SampleServer extends App {
  val ssc = AsynchronousServerSocketChannel.open()
    .setOption(StandardSocketOptions.SO_REUSEADDR, Boolean.box(true))
    .bind(new InetSocketAddress(8080))

  ssc.accept(ByteBuffer.allocate(8192), new CompletionHandler[AsynchronousSocketChannel, ByteBuffer](){
    def completed(channel: AsynchronousSocketChannel, byteBuffer: ByteBuffer): Unit = {
      ssc.accept(byteBuffer, this)
      channel.read(byteBuffer, null, new CompletionHandler[Integer, Null]() {
        def completed(r: Integer, att: Null): Unit = {
          byteBuffer.flip()
          channel.write(byteBuffer, null, new CompletionHandler[Integer, Null]() {
            def completed(r: Integer, att: Null): Unit = {channel.close(); byteBuffer.clear()}
            def failed(t: Throwable, att: Null): Unit = {channel.close(); byteBuffer.clear()}
          })
        }
        def failed(t: Throwable, att: Null): Unit = {channel.close()}
      })
    }
    def failed(t: Throwable, att: ByteBuffer): Unit = {t.printStackTrace()}
  })
  Console.readLine()
}

ソケットに書いたらそのままソケットクローズしちゃってるのでTelnetでなくブラウザで。
いい感じに凝縮されてます(凝集ではありません)。



Future 版はあっさりすぎて凝縮感は得られません。。

object SampleServer extends App {
  val ssc = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(8080))
  val buf = ByteBuffer.allocate(8192)
  while(true) {
    val channel = ssc.accept.get()
    channel.read(buf).get();  buf.flip()
    channel.write(buf).get(); buf.clear()
    channel.close()
  }
}


Scala らしさとか追い求めてませんので。