为什么选择Netty
netty是业界最流行的NIO框架之一,它的健壮型,功能,性能,可定制性和可扩展性都是首屈一指的,Hadoop的RPC框架Avro就使用了netty作为底层的通信框架,此外netty在互联网,大数据,网络游戏,企业应用,电信软件等众多行业都得到了成功的商业应用。正因为以上的一些特性,使得netty已经成为java NIO编程的首选框架。
构建netty开发环境
其实使用netty很简单,直接将其jar包引入到工程中即可使用。 去 http://netty.io/网站上下载最新版本的jar包(由于官网上netty5已经被废弃,但是这里仍然使用netty5进行开发, 可以考虑从csnd下载),我这里下载的为:netty-5.0.0.Alpha1.tar.bz2。这其实是一个压缩文件,解压这个文件,取里面的所有类集合到一起的那个jar包netty-all-5.0.0.Alpha1.jar即可。另外还需要注意的是,我这里使用的jdk版本是1.8。
第一个netty程序
这里利用netty来实现一个时钟的小程序,服务器端接收特定的指令然后将服务器时间返回给客户端,客户端按照一定的时间间隔往服务器端发送命令。
1 package com.rampage.netty.time; 2 3 import io.netty.bootstrap.ServerBootstrap; 4 import io.netty.channel.ChannelFuture; 5 import io.netty.channel.ChannelInitializer; 6 import io.netty.channel.ChannelOption; 7 import io.netty.channel.EventLoopGroup; 8 import io.netty.channel.nio.NioEventLoopGroup; 9 import io.netty.channel.socket.SocketChannel; 10 import io.netty.channel.socket.nio.NioServerSocketChannel; 11 12 /** 13 * 时钟程序的服务器端 14 * @author zyq 15 * 16 */ 17 public class TimeServer { 18 19 public static void main(String[] args) throws Exception { 20 new TimeServer().bind(8080); 21 } 22 23 public void bind(int port) throws Exception { 24 // 配置服务器的NIO线程组 25 EventLoopGroup bossGroup = new NioEventLoopGroup(); 26 EventLoopGroup workerGroup = new NioEventLoopGroup(); 27 28 try { 29 ServerBootstrap bootStrap = new ServerBootstrap(); 30 31 // 进行链式调用(每一次调用的返回结果都是ServerBootstrap) 32 // group带两个参数第一个表示给父(acceptor)用的EventExecutorGroup(其实就是线程池) 33 // 第二个参数表示子(client)线程池 34 // channel方法可以带一个ServerChannel类来创建进行IO操作的通道。 35 // option方法给Channel定制对应的选项 36 // childHandler方法用来处理Channel中的请求 37 bootStrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) 38 .option(ChannelOption.SO_BACKLOG, 1024).childHandler(new ChildChannelHandler()); 39 40 // 绑定端口,等待同步成功 41 // bind方法返回一个ChannelFuture类,就是相当于绑定端口并且创建一个新的channel 42 // sync方法会等待ChannelFuture的处理结束 43 ChannelFuture future = bootStrap.bind(port).sync(); 44 45 // 等待服务器监听端口关闭 46 future.channel().closeFuture().sync(); 47 } finally { 48 // 优雅地退出,释放线程资源 49 bossGroup.shutdownGracefully(); 50 workerGroup.shutdownGracefully(); 51 } 52 } 53 54 private class ChildChannelHandler extends ChannelInitializer<SocketChannel> { 55 56 @Override 57 protected void initChannel(SocketChannel arg0) throws Exception { 58 arg0.pipeline().addLast(new TimeServerHandler()); 59 } 60 61 } 62 }