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包,裡面包含了所有的程式碼,方便你進行依賴開發。這裡
/**
* 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中移除。