zoukankan      html  css  js  c++  java
  • Netty入门搭建

    什么是Netty

    Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性。

    为什么选择netty而不是使用NIO

    1、使用JDK自带的NIO需要了解太多的概念,编程复杂,一不小心bug横飞
    2、Netty底层IO模型随意切换,而这一切只需要做微小的改动,改改参数,Netty可以直接从NIO模型变身为IO模型
    3、Netty自带的拆包解包,异常检测等机制让你从NIO的繁重细节中脱离出来,让你只需要关心业务逻辑
    4、Netty解决了JDK的很多包括空轮询在内的bug
    5、Netty底层对线程,selector做了很多细小的优化,精心设计的reactor线程模型做到非常高效的并发处理
    6、自带各种协议栈让你处理任何一种通用协议都几乎不用亲自动手
    7、Netty社区活跃,遇到问题随时邮件列表或者issue
    8、Netty已经历各大rpc框架,消息中间件,分布式通信中间件线上的广泛验证,健壮性无比强大
    然后我们写编写一下netty的服务端和客户端的代码,了解一下
    Maven坐标:

    <dependency>
    	<groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.6.Final</version>
    </dependency>
    
    

    Server服务端代码

    class ServerHandler extends SimpleChannelHandler {
    
    	
    	/**
    	 * 通道关闭的时候触发
    	 */
    	@Override
    	public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
    		System.out.println("channelClosed");
    	}
    
    	/**
    	 * 必须是连接已经建立,关闭通道的时候才会触发.
    	 */
    	@Override
    	public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
    		super.channelDisconnected(ctx, e);
    		System.out.println("channelDisconnected");
    	}
    
    	/**
    	 * 捕获异常
    	 */
    	@Override
    	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
    		super.exceptionCaught(ctx, e);
    		System.out.println("exceptionCaught");
    
    	}
    
    	/**
    	 * 接受消息
    	 */
    	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
    		super.messageReceived(ctx, e);
    		System.out.println("服务器端收到客户端消息:"+e.getMessage());
    		//回复内容
    		ctx.getChannel().write("好的");
    	}
    }
    // netty 服务器端
    public class NettyServer {
    
    	public static void main(String[] args) {
    		// 创建服务类对象
    		ServerBootstrap serverBootstrap = new ServerBootstrap();
    		// 创建两个线程池 分别为监听监听端口 ,nio监听
    		ExecutorService boos = Executors.newCachedThreadPool();
    		ExecutorService worker = Executors.newCachedThreadPool();
    		// 设置工程 并把两个线程池加入中
    		serverBootstrap.setFactory(new NioServerSocketChannelFactory(boos, worker));
    		// 设置管道工厂
    		serverBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
    
    			public ChannelPipeline getPipeline() throws Exception {
    				ChannelPipeline pipeline = Channels.pipeline();
    				//将数据转换为string类型.
    				pipeline.addLast("decoder", new StringDecoder());
    				pipeline.addLast("encoder", new StringEncoder());
    				pipeline.addLast("serverHandler", new ServerHandler());
    				return pipeline;
    			}
    		});
    		// 绑定端口号
    		serverBootstrap.bind(new InetSocketAddress(9090));
    		System.out.println("netty server启动....");
    	}
    }
    
    

    1.boos对应,IOServer.java中的接受新连接线程,主要负责创建新连接
    2.worker对应 IOClient.java中的负责读取数据的线程,主要用于读取数据以及业务逻辑处理
    Netty客户端

    class ClientHandler extends SimpleChannelHandler {
    	
    	/**
    	 * 通道关闭的时候触发
    	 */
    	@Override
    	public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
    		System.out.println("channelClosed");
    	}
    
    	/**
    	 * 必须是连接已经建立,关闭通道的时候才会触发.
    	 */
    	@Override
    	public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
    		super.channelDisconnected(ctx, e);
    		System.out.println("channelDisconnected");
    	}
    
    	/**
    	 * 捕获异常
    	 */
    	@Override
    	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
    		super.exceptionCaught(ctx, e);
    		System.out.println("exceptionCaught");
    
    	}
    
    	/**
    	 * 接受消息
    	 */
    	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
    		super.messageReceived(ctx, e);
    		System.out.println("服务器端向客户端回复内容:"+e.getMessage());
    		//回复内容
    		ctx.getChannel().write("好的");
    	}
    
    }
    public class NettyClient {
    
    	public static void main(String[] args) {
    		System.out.println("netty client启动...");
    		// 创建客户端类
    		ClientBootstrap clientBootstrap = new ClientBootstrap();
    		// 线程池
    		ExecutorService boos = Executors.newCachedThreadPool();
    		ExecutorService worker = Executors.newCachedThreadPool();
    		clientBootstrap.setFactory(new NioClientSocketChannelFactory(boos, worker));
    		clientBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
    
    			public ChannelPipeline getPipeline() throws Exception {
    				ChannelPipeline pipeline = Channels.pipeline();
    				// 将数据转换为string类型.
    				pipeline.addLast("decoder", new StringDecoder());
    				pipeline.addLast("encoder", new StringEncoder());
    				pipeline.addLast("clientHandler", new ClientHandler());
    				return pipeline;
    
    			}
    		});
    		//连接服务端
    		ChannelFuture connect = clientBootstrap.connect(new InetSocketAddress("127.0.0.1", 9090));
    		Channel channel = connect.getChannel();
    		System.out.println("client start");
    		Scanner scanner=	new Scanner(System.in);
    		while (true) {
    			System.out.println("请输输入内容...");
    			channel.write(scanner.next());
    		}
    	}
    }
    
    

    Netty应用场景

    1.分布式开源框架中dubbo、Zookeeper,RocketMQ底层rpc通讯使用就是netty。
    2.游戏开发中,底层使用netty通讯。

  • 相关阅读:
    数组对象去重
    数组对象中key值为数组的数据处理成多个对应的数组对象
    数组对象相同的key值合并,并且把对应的id放到一个数组
    vue使用element-ui tabs切换 实现按需加载
    vue使用element-ui tabs切换echarts 解决宽度100% 问题
    递归获取所有JSON对象
    JS通过内核判断各种浏览器区分360与谷歌
    vue 跳转当前页面不刷新问题
    docker 常用命令
    java 比较时间的几种方法
  • 原文地址:https://www.cnblogs.com/Libbo/p/11571003.html
Copyright © 2011-2022 走看看