単なるエコーサーバを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 らしさとか追い求めてませんので。