zoukankan      html  css  js  c++  java
  • Netty简介

      Netty是一个NIO client-server框架。Netty提供了高层次的抽象来简化TCP和UDP服务器的编程。

      Netty框架由三部分组成:Transport Services, Protocol Support以及Core。

        Transport Services由Socket Datagram,HTTP Tunnel以及In-VM Pipe组成。

        Protocol Support由Http & WebSocket, SSL-StartTLS,Google Protobuf,zlib/gzip Compression,Large File Transfer,RTSP以及Legacy Text-Binary Protocols with Unit Testability组成。

        Core由Extensible Event Model,Universal Communication API和Zero-Copy-Capable Rich Byte Buffer组成。

      整个Netty的API都是异步的。

        Callbacks(回调)

          一个回调是被传递到并且执行完该方法。回调有个问题是当使用链式调用很多不同的方法会导致线性代码。

    public class Worker{
      public void doWork(){
        Fecher fetcher = new MyFetcher(new Data(1, 0));
        fetcher.fetchData(new FetcherCallback(){
          public void onError(Throwable cause){
            System.out.println("An error accour: " + cause.getMessage());
          }
         
          public void onData(Data data){
            System.out.println("Data received : " + data);
          }
        });
      }  
    }
    
    public interface Fetcher{
      void fetchData(FetcherCallback callback);
    }
    
    public class MyFetch implements Fetch{
      final Data data;
      public MyFetch(Data data){
        this.data = data;
      }
      public void fetchData(FetcherCallback callback){
        try{
          callback.onData(data);
        }catch(Exception e){
          callback.onError(e);
        }
      }
    }
    
    public interface FetcherCallback{
      void onData(Data data)  throw Exception;
      void onError(Throwable cause);    
    }
    
    public class Data{
      private int n;
      private int m;
    
      public Data(int n, int m){
        this.n = n;
        this.m = m;
      }
    }

        Futures

          Futures是一个抽象的概念,它表示一个值,该值可能在某一点变得可用。一个Future可以获得计算完的结果,要么获得计算失败后的异常。Java在java.util.concurrent包中附带了Future接口,它使用Executor异步执行。

    public class FutureExample{
      public static void main(String args[]) throws Exception{
        ExecutorService executor = Executors.newCachedThreadPool();
        Runnable task = new Runnable(){
          public void run(){
            System.out.println("task 1");
          }
        };
        Callable<Integer>  task2 = new Callable<Integer>(){
          public Integer call() throws Exception{
            return new Integer(100);
          }
        };
        Future<?> f1 = executor.sumbit(task1);
        Future<?> f2 = executor.sumbit(task2);
        System.out.println("task1 is completed? " + f1.isDone());
        System.out.println("task2 is completed? " + f2.isDone());
        while(fi.isDone){
          System.out.println("task1 completed");
          break;
        }
        while(f2.isDone()){
          System.out.println("return value by task2 :" + f2.get());
          break;
        }
      }
    }

      NIO是一个比较底层的APIs,他依赖于操作系统的IO APIS。Java实现了统一的接口来操作IO,其在所有操作系统中的工作行为是一样的。
      ByteBuffer是一个数据容器。ByteBuffer允许包装一个byte[]来获得一个实例。Netty通过一些APIs对ByteBuffer进行构造,使用和操作,以此来解决NIO中的一些限制。

      很多Channel的实现支持Gather和Scatter。这个功能允许从多个ByteBuffer中读入或写入到多个ByteBuffer中,以提升性能。操作系统底层知道如何处理这些被写入/读出。若要分割的数据在多个不同的ByteBuffer中,使用Gather/Scatter是比较好的方式。Gather/Scatter功能会导致内存泄漏,需在JDK1.7版本以上使用。

      

      一个简单的demo

        Netty服务器

          一个Netty服务器主要有两部分组成:配置服务器功能(如线程,端口)以及实现服务器处理程序,它包含业务逻辑,决定当有一个请求连接或接收数据时该做什么。

          启动服务器应先创建一个ServerBootstrap对象,指定NioEventLoopGroup来接受和处理新连接,指定通道类型为NioServerSocketChannel,设置InetSocketAddress让服务器监听某个端口已等待客户端连接。调用childHandler指定连接后调用的ChannelHandler,该方法接受一个ChannelInitializer类型的参数,实现其initChannel方法,该方法用来设置ChannelHandler。直到绑定完成调用sync()方法会阻塞直到服务器完成绑定,然后等待通道关闭。

        Netty客户端

          一个Netty的客户端由连接服务器,写数据到服务器,等待接受服务器返回相同的数据和关闭连接四个步骤组成。

          创建一个客户端包含:创建Bootstrap对象用来引导启动客户端;创建EventLoopGroup对象并设置到Bootstrap中,EventLoopGroup可以理解为一个线程池,这个线程池用来处理连接,接收数据,发送数据;创建InetSocketAddress并设置到Boostrap中,InetSocketAddress是指定连接的服务器地址;添加一个ChannelHandler,客户端成功连接服务器后就会被执行;调用Bootstrap.connect()来连接服务器;最后关闭EventLoopGroup来释放资源。

          使用SimpleChannelInboundHandler的ChannelHandler来处理业务,通过重写父类的三个方法来处理感兴趣的事件:channelActive():客户端连接服务器后被调用;channelRead():从服务器接收到数据后调用;exceptionCaught():发生异常时被调用

      

  • 相关阅读:
    浅析MySQL二进制日志
    MySQL升级
    浅析MySQL复制
    MySQL关于exists的一个bug
    TokuDB存储引擎
    MySQL中RESET SLAVE和RESET MASTER的区别
    MySQL半同步复制
    MySQL线程池
    分析MariaDB初始化脚本mysql_install_db
    Python装饰器
  • 原文地址:https://www.cnblogs.com/forerver-elf/p/7201251.html
Copyright © 2011-2022 走看看