netty小案例demo

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

#netty 服务端ip
nioServerIp=127.0.0.1
#netty 服务端端口
nioServerPort=19990


2.服务段代码:

package netty.test;


import java.io.InputStream;

import java.util.Properties;



/** properties文件加载类
 * @author xiefg
 *
 */
public class Configuration {
	
    private static Properties SYSTEM_CONFIG = new Properties();

    
    public static String fileName = "";
       
    private static final String PATH_SERVER_CONF = "netty/config/config.properties";
    

    public static void init() {
        try {
            InputStream inputStream = null;
            ClassLoader classLoader = null;
            classLoader = Thread.currentThread().getContextClassLoader();
            inputStream = classLoader.getResourceAsStream(PATH_SERVER_CONF);
            SYSTEM_CONFIG.load(inputStream);
            
        	fileName = "";
			int index = PATH_SERVER_CONF.lastIndexOf("/") == -1 ? PATH_SERVER_CONF
					.lastIndexOf("\\") : PATH_SERVER_CONF.lastIndexOf("/");
			if (index > 0) {
				fileName = PATH_SERVER_CONF.substring(index + 1);
			}
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return;
    }

    public static String getProperty(String key, String defaultValue) {
        try {
            return SYSTEM_CONFIG.getProperty(key, defaultValue);
        } catch (Exception e) {
            return null;
        }
    }

    public static String getProperty(String key) {
		try {
			String value = SYSTEM_CONFIG.getProperty(key);
			return value;
		} catch (Exception e) {
			return null;
		}
	}

    public static void main(String[] args) {
    	init();
    	System.out.println(Configuration.getProperty("nioServerIp"));
		
	}
}


package netty.test;


import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;
/***
 * 
  * @ClassName: NettyServer
  * @Description: TODO  netty 提供服务
  * @author xiefg
  * @date 2016年8月4日 下午5:02:05
  *
 */
public class NettyServer {
	//ip 地址
    private static   String IP = "127.0.0.1";
    //默认端口
    private  static  int PORT = 5656;
    
    private static final int BIZGROUPSIZE = Runtime.getRuntime().availableProcessors()*2;
    
    private static final int BIZTHREADSIZE = 100;
    private static final EventLoopGroup bossGroup = new NioEventLoopGroup(BIZGROUPSIZE);
    private static final EventLoopGroup workerGroup = new NioEventLoopGroup(BIZTHREADSIZE);
    public static void init() throws Exception {
    	
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bossGroup, workerGroup);
        bootstrap.channel(NioServerSocketChannel.class);
        bootstrap.childHandler(new ChannelInitializer<Channel>() {

            @Override
            protected void initChannel(Channel ch) throws Exception {
                // TODO Auto-generated method stub
                ChannelPipeline pipeline = ch.pipeline();
                 pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
                    pipeline.addLast(new LengthFieldPrepender(4));
                    pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
                    pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
                    pipeline.addLast(new ServerHandler());
            }
            
        });
        IP =Configuration.getProperty("nioServerIp");
        PORT=Integer.parseInt(Configuration.getProperty("nioServerPort"));
        System.out.println("【TCP服务器IP】"+IP+"【TCP服务器PORT】"+PORT);
          ChannelFuture f = bootstrap.bind(IP, PORT).sync();
            f.channel().closeFuture().sync();
            System.out.println("TCP服务器已启动");
        }

    
    
        protected static void shutdown() {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }

        public static void main(String[] args) throws Exception {
            System.out.println("初始化配置文件...");
            Configuration.init();   
            System.out.println("开始启动TCP服务器...");
            NettyServer.init();
//         HelloServer.shutdown();
        }
}


package netty.test;


import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
/**
 * 
  * @ClassName: ServerHandler
  * @Description: TODO
  * @author xiefg
  * @date 2016年8月4日 下午5:34:19
  *
 */
public class ServerHandler extends ChannelInboundHandlerAdapter {
    
    
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
       
        System.out.println("server receive message :"+ msg);
        ctx.channel().writeAndFlush("yes server already accept your message" + msg);
        ctx.close();
    }
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("【channelActive】。。。");
    }
      @Override
   public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("【exception is general】");
    }
}
3、客户端代码

package netty.test;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;

/**
 * 
  * @ClassName: NettyClient
  * @Description: TODO
  * @author xiefg
  * @date 2016年8月4日 下午5:46:43
  *
 */
public class NettyClient implements Runnable {
	
    @Override
     public void run() {
            EventLoopGroup group = new NioEventLoopGroup();
            try {
                Bootstrap b = new Bootstrap();
                b.group(group);
                b.channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true);
                b.handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
                        pipeline.addLast("frameEncoder", new LengthFieldPrepender(4));
                        pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
                        pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));

                        pipeline.addLast("handler", new Client());
                    }
                });
             
             ChannelFuture f = b.connect("127.0.0.1", 19990).sync();
             f.channel().writeAndFlush("Netty Hello Service!"+Thread.currentThread().getName()+":--->:"+Thread.currentThread().getId());
             f.channel().closeFuture().sync();
             
               

            } catch (Exception e) {

            } finally {
                group.shutdownGracefully();
            }
        }

        public static void main(String[] args) throws Exception {
        	
            for (int i = 0; i < 10; i++) {
                new Thread(new NettyClient(),"【this thread】 "+i).start();
            }
        }
}


package netty.test;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
/**
 * 
  * @ClassName: Client
  * @Description: TODO
  * @author xiefg
  * @date 2016年8月4日 下午6:18:08
  *
 */
public class Client extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("【client接收到服务器返回的消息】:" + msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("【client exception is general】");
    }
}

启动服务端如下图:



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



服务端接收消息如下图




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值