ScalaはNettyを使用

4011 ワード

JAvaは書くことができてscalaに変えても書くことができて、その上scalaは文法の上でjavaよりずっと簡潔で、だからscalaで簡単なnetty demoを書いてみます
サービス側
ServerHandlerメッセージの処理
class ServerHandler extends ChannelInboundHandlerAdapter{

  /**
    *            
    */
  override def channelActive(ctx: ChannelHandlerContext) :Unit ={
    println("          ")
  }

  /**
    *            
    */
  override def channelRead(ctx: ChannelHandlerContext, msg: scala.Any): Unit = {
    println("channelRead invoked            " + msg)

    val back = "connection success"
    println("    " + back)
    ctx.writeAndFlush(back)
  }
}

NettyServer
class NettyServer {

  def bind(host: String, port: Int): Unit = {
    //         
    //            
    val bossGroup = new NioEventLoopGroup
    //    SocketChannel     
    val workerGroup = new NioEventLoopGroup

    try {
      // Netty    NIO         ,           
      val bootStrap = new ServerBootstrap
      //   NIO          ServerBootstrap
      bootStrap.group(bossGroup, workerGroup)
        //  NioServerSocketChannel
        .channel(classOf[NioServerSocketChannel])
        //  I/O     
        .childHandler(new ChannelInitializer[SocketChannel] {
        override def initChannel(ch: SocketChannel): Unit = {
          //   
          ch.pipeline().addLast(new StringDecoder)
          ch.pipeline().addLast(new StringEncoder)
          ch.pipeline().addLast(new ServerHandler)
        }
      })
      //    ,  sync          
      val channelFuture = bootStrap.bind(host, port).sync()
      println("     ")
      channelFuture.channel().closeFuture().sync()

    } finally {
      bossGroup.shutdownGracefully()
      workerGroup.shutdownGracefully()
    }
  }
}

object NettyServer {
  def main(args: Array[String]): Unit = {
    val host = "localhost"
    val port = 8083
    val server = new StringNettyServer
    println(s"IP$host,   $port")
    server.bind(host, port)
  }
}

クライアント
ClientHandler
class ClientHandler extends ChannelInboundHandlerAdapter {
  /**
    *            
    */
  override def channelActive(ctx: ChannelHandlerContext): Unit = {
    println("           ")
    val content = "  ,     "
    ctx.writeAndFlush(content)
  }


  override def channelRead(ctx: ChannelHandlerContext, msg: scala.Any): Unit = {
    println("        " + msg)
  }
}


NettyClient
class StringNettyClient {

  def connect(host: String, port: Int): Unit = {
    //     NIO   
    val eventGroup = new NioEventLoopGroup
    //          
    val bootStrap = new Bootstrap

    try {
      bootStrap.group(eventGroup)
        //  NioSocketChannel
        .channel(classOf[NioSocketChannel])
        //  I/O     
        .handler(new ChannelInitializer[SocketChannel] {
        override def initChannel(ch: SocketChannel): Unit = {
          ch.pipeline().addLast(new StringEncoder)
          ch.pipeline().addLast(new StringDecoder)
          ch.pipeline().addLast(new ClientHandler)
        }
      })
      //        
      val channelFuture = bootStrap.connect(host, port).sync()
      //      
      channelFuture.channel().closeFuture().sync()

    } finally {
      //     ,       
      eventGroup.shutdownGracefully()
    }
  }
}

object StringNettyClient {
  def main(args: Array[String]): Unit = {
    val host = "localhost"
    val port = 8083
    val client = new StringNettyClient
    client.connect(host, port)
  }
}

うんてん
サービスを開始
IPlocalhost,   8083
     

クライアントを再オープン
           

サービス側が受信してフィードバックする
           
             ,     
    connection success

クライアント受信サービス側の結果
        connection success

まとめ
上記の通信はStringEncoderエンコーダとStringDecoderデコーダを用いているので、ctx.writeAndFlush()メソッドを呼び出すときに文字列を入力し、自動的に処理することができる.