netty案例

Netty是业界最流行的NIO框架之一,它的健壮性、功能、性能、可定制性和可扩展性在同类框架中都是首屈一指的,它已经得到成百上千的商用项目验证,例如Hadoop的RPC框架avro使用Netty作为底层通信框架。很多其它业界主流的RPC框架,也使用Netty来构建高性能的异步通信能力。

通过对Netty的分析,我们将它的优点总结如下:

1)      API使用简单,开发门槛低;

2)      功能强大,预置了多种编解码功能,支持多种主流协议;

3)      定制能力强,可以通过ChannelHandler对通信框架进行灵活的扩展;

4)      性能高,通过与其它业界主流的NIO框架对比,Netty的综合性能最优;

5)      成熟、稳定,Netty修复了已经发现的所有JDK NIO BUG,业务开发人员不需要再为NIO的BUG而烦恼;

6)      社区活跃,版本迭代周期短,发现的BUG可以被及时修复,同时,更多的新功能会被加入;

7)      经历了大规模的商业应用考验,质量已经得到验证。在互联网、大数据、网络游戏、企业应用、电信软件等众多行业得到成功商用,证明了它可以完全满足不同行业的商业应用。

正是因为这些优点,Netty逐渐成为Java NIO编程的首选框架。

接下来看一个demo 

1、用到的jar


配置文件  config.properties

[html]  view plain  copy
  1. #netty 服务端ip  
  2. nioServerIp=127.0.0.1  
  3. #netty 服务端端口  
  4. nioServerPort=19990  


2.服务段代码:

[java]  view plain  copy
  1. package netty.test;  
  2.   
  3.   
  4. import java.io.InputStream;  
  5.   
  6. import java.util.Properties;  
  7.   
  8.   
  9.   
  10. /** properties文件加载类 
  11.  * @author xiefg 
  12.  * 
  13.  */  
  14. public class Configuration {  
  15.       
  16.     private static Properties SYSTEM_CONFIG = new Properties();  
  17.   
  18.       
  19.     public static String fileName = "";  
  20.          
  21.     private static final String PATH_SERVER_CONF = "netty/config/config.properties";  
  22.       
  23.   
  24.     public static void init() {  
  25.         try {  
  26.             InputStream inputStream = null;  
  27.             ClassLoader classLoader = null;  
  28.             classLoader = Thread.currentThread().getContextClassLoader();  
  29.             inputStream = classLoader.getResourceAsStream(PATH_SERVER_CONF);  
  30.             SYSTEM_CONFIG.load(inputStream);  
  31.               
  32.             fileName = "";  
  33.             int index = PATH_SERVER_CONF.lastIndexOf("/") == -1 ? PATH_SERVER_CONF  
  34.                     .lastIndexOf("\\") : PATH_SERVER_CONF.lastIndexOf("/");  
  35.             if (index > 0) {  
  36.                 fileName = PATH_SERVER_CONF.substring(index + 1);  
  37.             }  
  38.             inputStream.close();  
  39.         } catch (Exception e) {  
  40.             e.printStackTrace();  
  41.         }  
  42.         return;  
  43.     }  
  44.   
  45.     public static String getProperty(String key, String defaultValue) {  
  46.         try {  
  47.             return SYSTEM_CONFIG.getProperty(key, defaultValue);  
  48.         } catch (Exception e) {  
  49.             return null;  
  50.         }  
  51.     }  
  52.   
  53.     public static String getProperty(String key) {  
  54.         try {  
  55.             String value = SYSTEM_CONFIG.getProperty(key);  
  56.             return value;  
  57.         } catch (Exception e) {  
  58.             return null;  
  59.         }  
  60.     }  
  61.   
  62.     public static void main(String[] args) {  
  63.         init();  
  64.         System.out.println(Configuration.getProperty("nioServerIp"));  
  65.           
  66.     }  
  67. }  


[java]  view plain  copy
  1. package netty.test;  
  2.   
  3.   
  4. import io.netty.bootstrap.ServerBootstrap;  
  5. import io.netty.channel.Channel;  
  6. import io.netty.channel.ChannelFuture;  
  7. import io.netty.channel.ChannelInitializer;  
  8. import io.netty.channel.ChannelPipeline;  
  9. import io.netty.channel.EventLoopGroup;  
  10. import io.netty.channel.nio.NioEventLoopGroup;  
  11. import io.netty.channel.socket.nio.NioServerSocketChannel;  
  12. import io.netty.handler.codec.LengthFieldBasedFrameDecoder;  
  13. import io.netty.handler.codec.LengthFieldPrepender;  
  14. import io.netty.handler.codec.string.StringDecoder;  
  15. import io.netty.handler.codec.string.StringEncoder;  
  16. import io.netty.util.CharsetUtil;  
  17. /*** 
  18.  *  
  19.   * @ClassName: NettyServer 
  20.   * @Description: TODO  netty 提供服务 
  21.   * @author xiefg 
  22.   * @date 2016年8月4日 下午5:02:05 
  23.   * 
  24.  */  
  25. public class NettyServer {  
  26.     //ip 地址  
  27.     private static   String IP = "127.0.0.1";  
  28.     //默认端口  
  29.     private  static  int PORT = 5656;  
  30.       
  31.     private static final int BIZGROUPSIZE = Runtime.getRuntime().availableProcessors()*2;  
  32.       
  33.     private static final int BIZTHREADSIZE = 100;  
  34.     private static final EventLoopGroup bossGroup = new NioEventLoopGroup(BIZGROUPSIZE);  
  35.     private static final EventLoopGroup workerGroup = new NioEventLoopGroup(BIZTHREADSIZE);  
  36.     public static void init() throws Exception {  
  37.           
  38.         ServerBootstrap bootstrap = new ServerBootstrap();  
  39.         bootstrap.group(bossGroup, workerGroup);  
  40.         bootstrap.channel(NioServerSocketChannel.class);  
  41.         bootstrap.childHandler(new ChannelInitializer<Channel>() {  
  42.   
  43.             @Override  
  44.             protected void initChannel(Channel ch) throws Exception {  
  45.                 // TODO Auto-generated method stub  
  46.                 ChannelPipeline pipeline = ch.pipeline();  
  47.                  pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0404));  
  48.                     pipeline.addLast(new LengthFieldPrepender(4));  
  49.                     pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));  
  50.                     pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));  
  51.                     pipeline.addLast(new ServerHandler());  
  52.             }  
  53.               
  54.         });  
  55.         IP =Configuration.getProperty("nioServerIp");  
  56.         PORT=Integer.parseInt(Configuration.getProperty("nioServerPort"));  
  57.         System.out.println("【TCP服务器IP】"+IP+"【TCP服务器PORT】"+PORT);  
  58.           ChannelFuture f = bootstrap.bind(IP, PORT).sync();  
  59.             f.channel().closeFuture().sync();  
  60.             System.out.println("TCP服务器已启动");  
  61.         }  
  62.   
  63.       
  64.       
  65.         protected static void shutdown() {  
  66.             workerGroup.shutdownGracefully();  
  67.             bossGroup.shutdownGracefully();  
  68.         }  
  69.   
  70.         public static void main(String[] args) throws Exception {  
  71.             System.out.println("初始化配置文件...");  
  72.             Configuration.init();     
  73.             System.out.println("开始启动TCP服务器...");  
  74.             NettyServer.init();  
  75. //         HelloServer.shutdown();  
  76.         }  
  77. }  


[java]  view plain  copy
  1. package netty.test;  
  2.   
  3.   
  4. import io.netty.channel.ChannelHandlerContext;  
  5. import io.netty.channel.ChannelInboundHandlerAdapter;  
  6. /** 
  7.  *  
  8.   * @ClassName: ServerHandler 
  9.   * @Description: TODO 
  10.   * @author xiefg 
  11.   * @date 2016年8月4日 下午5:34:19 
  12.   * 
  13.  */  
  14. public class ServerHandler extends ChannelInboundHandlerAdapter {  
  15.       
  16.       
  17.     @Override  
  18.     public void channelRead(ChannelHandlerContext ctx, Object msg)  
  19.             throws Exception {  
  20.          
  21.         System.out.println("server receive message :"+ msg);  
  22.         ctx.channel().writeAndFlush("yes server already accept your message" + msg);  
  23.         ctx.close();  
  24.     }  
  25.     @Override  
  26.     public void channelActive(ChannelHandlerContext ctx) throws Exception {  
  27.         // TODO Auto-generated method stub  
  28.         System.out.println("【channelActive】。。。");  
  29.     }  
  30.       @Override  
  31.    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {  
  32.         System.out.println("【exception is general】");  
  33.     }  
  34. }  
3、客户端代码

[java]  view plain  copy
  1. package netty.test;  
  2.   
  3. import io.netty.bootstrap.Bootstrap;  
  4. import io.netty.channel.ChannelFuture;  
  5. import io.netty.channel.ChannelInitializer;  
  6. import io.netty.channel.ChannelOption;  
  7. import io.netty.channel.ChannelPipeline;  
  8. import io.netty.channel.EventLoopGroup;  
  9. import io.netty.channel.nio.NioEventLoopGroup;  
  10. import io.netty.channel.socket.SocketChannel;  
  11. import io.netty.channel.socket.nio.NioSocketChannel;  
  12. import io.netty.handler.codec.LengthFieldBasedFrameDecoder;  
  13. import io.netty.handler.codec.LengthFieldPrepender;  
  14. import io.netty.handler.codec.string.StringDecoder;  
  15. import io.netty.handler.codec.string.StringEncoder;  
  16. import io.netty.util.CharsetUtil;  
  17.   
  18. /** 
  19.  *  
  20.   * @ClassName: NettyClient 
  21.   * @Description: TODO 
  22.   * @author xiefg 
  23.   * @date 2016年8月4日 下午5:46:43 
  24.   * 
  25.  */  
  26. public class NettyClient implements Runnable {  
  27.       
  28.     @Override  
  29.      public void run() {  
  30.             EventLoopGroup group = new NioEventLoopGroup();  
  31.             try {  
  32.                 Bootstrap b = new Bootstrap();  
  33.                 b.group(group);  
  34.                 b.channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true);  
  35.                 b.handler(new ChannelInitializer<SocketChannel>() {  
  36.                     @Override  
  37.                     protected void initChannel(SocketChannel ch) throws Exception {  
  38.                         ChannelPipeline pipeline = ch.pipeline();  
  39.                         pipeline.addLast("frameDecoder"new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0404));  
  40.                         pipeline.addLast("frameEncoder"new LengthFieldPrepender(4));  
  41.                         pipeline.addLast("decoder"new StringDecoder(CharsetUtil.UTF_8));  
  42.                         pipeline.addLast("encoder"new StringEncoder(CharsetUtil.UTF_8));  
  43.   
  44.                         pipeline.addLast("handler"new Client());  
  45.                     }  
  46.                 });  
  47.                
  48.              ChannelFuture f = b.connect("127.0.0.1"19990).sync();  
  49.              f.channel().writeAndFlush("Netty Hello Service!"+Thread.currentThread().getName()+":--->:"+Thread.currentThread().getId());  
  50.              f.channel().closeFuture().sync();  
  51.                
  52.                  
  53.   
  54.             } catch (Exception e) {  
  55.   
  56.             } finally {  
  57.                 group.shutdownGracefully();  
  58.             }  
  59.         }  
  60.   
  61.         public static void main(String[] args) throws Exception {  
  62.               
  63.             for (int i = 0; i < 10; i++) {  
  64.                 new Thread(new NettyClient(),"【this thread】 "+i).start();  
  65.             }  
  66.         }  
  67. }  


[java]  view plain  copy
  1. package netty.test;  
  2.   
  3. import io.netty.channel.ChannelHandlerContext;  
  4. import io.netty.channel.ChannelInboundHandlerAdapter;  
  5. /** 
  6.  *  
  7.   * @ClassName: Client 
  8.   * @Description: TODO 
  9.   * @author xiefg 
  10.   * @date 2016年8月4日 下午6:18:08 
  11.   * 
  12.  */  
  13. public class Client extends ChannelInboundHandlerAdapter {  
  14.     @Override  
  15.     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {  
  16.         System.out.println("【client接收到服务器返回的消息】:" + msg);  
  17.     }  
  18.   
  19.     @Override  
  20.     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {  
  21.         System.out.println("【client exception is general】");  
  22.     }  
  23. }  

启动服务端如下图:



启动服务端后客户端 如下图



服务端接收消息如下图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值