1. 程式人生 > >Java NIO框架Netty教程(十七)

Java NIO框架Netty教程(十七)

最近很多人問我有沒有Netty4的Hello World樣例,很早之前知道Netty要出4,當時只知道4的包名完全邊了,因為Netty從JBoss中獨立出來了,並採用了新的netty.io的域名,但是沒想到程式碼也有這麼大的調整。

既然答應了別人,就抽時間看一下Netty4,也順便補充一下自己的知識。還是先從最簡單的Hello world開始吧。下面程式碼基於最近版的Netty4,netty4.0.12-Final。由於Netty4最程式碼進行了分包,分了很多工程,有可能會對你的開發造成困擾,不過Netty4也提供了一個netty4-all的jar包,裡面包含了所有的程式碼,方便你進行依賴開發。這裡

OneCoder用的就是該jar包。

/**
 * Netty4 服務端程式碼
 *
 * @author lihzh
 * @date 2013年11月15日 下午1:10:06
 * @website http://www.coderli.com
 */
public class HelloWorldServer {

      public static void main(String[] args) {
           // EventLoop 代替原來的 ChannelFactory
          EventLoopGroup bossGroup = new NioEventLoopGroup
(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); // server端採用簡潔的連寫方式,client端才用分段普通寫法。 serverBootstrap.group(bossGroup, workerGroup) .channel(
NioServerSocketChannel. class ) .childHandler( new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast( new HelloServerHandler()); } }).option(ChannelOption. SO_KEEPALIVE , true ); ChannelFuture f = serverBootstrap.bind(8000).sync(); f.channel().closeFuture().sync(); } catch (InterruptedException e) { } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } private static class HelloServerHandler extends ChannelInboundHandlerAdapter { /** * 當繫結到服務端的時候觸發,列印"Hello world, I'm client." * * @alia OneCoder * @author lihzh * @date 2013年11月16日 上午12:50:47 */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System. out .println("Hello world, I'm server."); } } }
/**
 * Netty4 客戶端程式碼
 * @author OneCoder
 * @date 2013年11月15日 下午1:28:21
 * @website http://www.coderli.com
 */
public class HelloWorldClient {

      public static void main(String args[]) {
           // Client服務啟動器 3.x的ClientBootstrap 改為Bootstrap,且建構函式變化很大,這裡用無參構造。
          Bootstrap bootstrap = new Bootstrap();
           // 指定channel型別
          bootstrap.channel(NioSocketChannel. class );
           // 指定Handler
          bootstrap.handler( new HelloClientHandler());
           // 指定EventLoopGroup
          bootstrap.group( new NioEventLoopGroup());
           // 連線到本地的8000埠的服務端
          bootstrap.connect( new InetSocketAddress("127.0.0.1" , 8000));
     }

      private static class HelloClientHandler extends
              ChannelInboundHandlerAdapter {

           /**
           * 當繫結到服務端的時候觸發,列印"Hello world, I'm client."
           *
           * @alia OneCoder
           * @author lihzh
           * @date 2013年11月16日 上午12:50:47
           */
           @Override
           public void channelActive(ChannelHandlerContext ctx) throws Exception {
              System. out .println("Hello world, I'm client.");
          }
     }
}

一些主要的變化和對比註釋在程式碼中。簡單補充介紹幾點:

NioEventLoopGroup 是一個處理I/O操作的多執行緒事件環。即為Netty4裡的執行緒池,在3.x裡,一個Channel是由ChannelFactory建立的,同時新建立的Channel會自動註冊到一個隱藏的I/O執行緒。 4.0使用新的名為EventLoopGroup的介面來替換ChannelFactory,它由一個或多個EventLoop來構成。一個新的 Channel不會自動註冊到EventLoopGroup,但使用者可以顯式呼叫EventLoopGroup.register()來註冊。在Server端的Bootstrap引數中,有兩個EventLoopGroup,第一個通常稱為’boss’,用於接收發來的連線請求。第二個稱為’worker’,,用於處理boss接受並且註冊給worker的連線中的資訊。

ChannelInitializer是一個特殊的handler,用於方便的配置使用者自定義的handler實現,如程式碼中所示。在channelRegistered的生命週期中會觸發使用者複寫的initChannel(C ch)方法,並且在呼叫後會講自身從channelPipeline中移除。