<progress id="7nnbd"><big id="7nnbd"><em id="7nnbd"></em></big></progress>

<big id="7nnbd"><meter id="7nnbd"></meter></big>
<progress id="7nnbd"><meter id="7nnbd"><cite id="7nnbd"></cite></meter></progress><meter id="7nnbd"></meter>

      <address id="7nnbd"></address>

          為了賬號安全,請及時綁定郵箱和手機立即綁定

          Netty入門

          2018.12.25 18:01 1647瀏覽

          Netty是一個異步的事件驅動網絡框架,使用Netty可以研發高性能的私有協議,將業務邏輯和網絡進行解耦,通過Netty我們可以實現一些常用的協議,如HTTP。

          基本概念

          Channel

          Channel是NIO的基礎,它代表一個連接,通過這個鏈接可以進行IO操作,例如讀和寫。

          Future

          在Netty的Channel中的每一個IO操作都是非阻塞的。
          這就意味著每一個操作都是立刻返回結果的。在Java標準庫中有Future接口,但是我們使用Future的時候只能詢問這個操作是否執行完成,或者阻塞當前的線程直到結果完成,這不是Netty想要的。

          Netty實現了自己的ChannelFuture接口,我們可以傳遞一個回調到ChannelFuture,當操作完成的時候才會執行回調。

          Events 和 Handlers

          Netty使用的是事件驅動的應用設計,因此Handler處理的數據流,在管道中是鏈式的事件。事件和Handler可以被 輸入 和 輸出的數據流進行關聯。

          輸入(Inbound)事件可以如下:

          • Channel激活和滅活
          • 讀操作事件
          • 異常事件
          • 用戶事件

          輸出(Outbound)事件比較簡單,一般是打開和關閉連接,寫入和刷新數據。

          Encoder 和 Decoder

          因為我們要處理網絡協議,需要操作數據的序列化和反序列化。

          代碼

          來個實際的案例:

          1. 新建項目,添加maven依賴
              <properties>
                  <netty-all.version>4.1.6.Final</netty-all.version>
              </properties>
          
          
              <dependencies>
                  <dependency>
                      <groupId>io.netty</groupId>
                      <artifactId>netty-all</artifactId>
                      <version>${netty-all.version}</version>
                  </dependency>
              </dependencies>
          
          1. 創建數據的pojo
          public class RequestData {
              private int intValue;
              private String stringValue;
          
              // getter 和 setter
              // toString方法
          }
          
          public class ResponseData {
              private int intValue;
              
              // getter 和 setter
              // toString方法    
          }
          
          
          1. 創建Encoder和Decoder
          public class RequestDataEncoder extends MessageToByteEncoder<RequestData> {
          
              private final Charset charset = Charset.forName("UTF-8");
          
              @Override
              protected void encode(ChannelHandlerContext channelHandlerContext, RequestData msg, ByteBuf out) throws Exception {
                  out.writeInt(msg.getIntValue());
                  out.writeInt(msg.getStringValue().length());
                  out.writeCharSequence(msg.getStringValue(), charset);
              }
          }
          
          public class ResponseDataDecoder extends ReplayingDecoder<ResponseData> {
          
              @Override
              protected void decode(ChannelHandlerContext ctx,
                                    ByteBuf in, List<Object> out) throws Exception {
          
                  ResponseData data = new ResponseData();
                  data.setIntValue(in.readInt());
                  out.add(data);
              }
          }
          
          
          public class RequestDecoder extends ReplayingDecoder<RequestData> {
          
              private final Charset charset = Charset.forName("UTF-8");
          
              @Override
              protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception {
          
                      RequestData data = new RequestData();
                      data.setIntValue(in.readInt());
                      int strLen = in.readInt();
                      data.setStringValue(
                              in.readCharSequence(strLen, charset).toString());
                      out.add(data);
              }
          }
          
          
          public class ResponseDataEncoder extends MessageToByteEncoder<ResponseData> {
              @Override
              protected void encode(ChannelHandlerContext channelHandlerContext, ResponseData msg, ByteBuf out) throws Exception {
                  out.writeInt(msg.getIntValue());
              }
          }
          
          
          1. 創建請求的處理器
          public class ProcessingHandler extends ChannelInboundHandlerAdapter {
          
              @Override
              public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                  RequestData requestData = (RequestData) msg;
                  ResponseData responseData = new ResponseData();
                  responseData.setIntValue(requestData.getIntValue() * 2);
                  ChannelFuture future = ctx.writeAndFlush(responseData);
                  future.addListener(ChannelFutureListener.CLOSE);
                  System.out.println(requestData);
              }
          }
          
          
          public class ClientHandler extends ChannelInboundHandlerAdapter {
          
              @Override
              public void channelActive(ChannelHandlerContext ctx)
                      throws Exception {
          
                  RequestData msg = new RequestData();
                  msg.setIntValue(123);
                  msg.setStringValue(
                          "正常工作");
                  ChannelFuture future = ctx.writeAndFlush(msg);
              }
          
              @Override
              public void channelRead(ChannelHandlerContext ctx, Object msg)
                      throws Exception {
                  System.out.println((ResponseData)msg);
                  ctx.close();
              }
          }
          
          1. 創建服務端應用
          public class NettyServer {
              private int port;
              
          
              public NettyServer(int port) {
                  this.port = port;
              }
          
              public static void main(String[] args) throws Exception {
          
                  int port = args.length > 0
                          ? Integer.parseInt(args[0]) : 9003;
          
                  new NettyServer(port).run();
              }
          
              public void run() throws Exception {
                  EventLoopGroup bossGroup = new NioEventLoopGroup();
                  EventLoopGroup workerGroup = new NioEventLoopGroup();
                  try {
                      ServerBootstrap b = new ServerBootstrap();
                      b.group(bossGroup, workerGroup)
                              .channel(NioServerSocketChannel.class)
                              .childHandler(new ChannelInitializer<SocketChannel>() {
                                  @Override
                                  public void initChannel(SocketChannel ch)
                                          throws Exception {
                                      ch.pipeline().addLast(new RequestDecoder(),
                                              new ResponseDataEncoder(),
                                              new ProcessingHandler());
                                  }
                              }).option(ChannelOption.SO_BACKLOG, 128)
                              .childOption(ChannelOption.SO_KEEPALIVE, true);
          
                      ChannelFuture f = b.bind(port).sync();
                      f.channel().closeFuture().sync();
                  } finally {
                      workerGroup.shutdownGracefully();
                      bossGroup.shutdownGracefully();
                  }
              }
          }
          
          
          1. 創建客戶端應用
          public class NettyClient {
              public static void main(String[] args) throws Exception {
          
                  String host = "127.0.0.1";
                  int port = 9003;
                  EventLoopGroup workerGroup = new NioEventLoopGroup();
          
                  try {
                      Bootstrap b = new Bootstrap();
                      b.group(workerGroup)
                              .channel(NioSocketChannel.class)
                              .option(ChannelOption.SO_KEEPALIVE, true)
                              .handler(new ChannelInitializer<SocketChannel>() {
          
                                  @Override
                                  public void initChannel(SocketChannel ch)
                                          throws Exception {
                                      ch.pipeline().addLast(new RequestDataEncoder(),
                                              new ResponseDataDecoder(), new ClientHandler());
                                  }
                              });
          
                      ChannelFuture f = b.connect(host, port).sync();
          
                      f.channel().closeFuture().sync();
                  } finally {
                      workerGroup.shutdownGracefully();
                  }
              }
          }
          
          1. 運行服務端和客戶端

          可見正常工作

          最后

          這里我們只是對Netty進行簡單的介紹,介紹了它一些基本的概念,然后演示了一個例子。后續我們會對Netty進行更深入的研究

          參考

          點擊查看更多內容

          本文首次發布于慕課網 ,轉載請注明出處,謝謝合作

          2人點贊

          若覺得本文不錯,就分享一下吧!

          評論

          相關文章推薦

          正在加載中
          意見反饋 邀請有獎 幫助中心 APP下載
          官方微信

          舉報

          0/150
          提交
          取消
          五福彩票 博罗 | 邯郸 | 吉林 | 汕尾 | 甘孜 | 芜湖 | 马鞍山 | 济南 | 甘南 | 广汉 | 喀什 | 武安 | 澳门澳门 | 招远 | 伊犁 | 中卫 | 东营 | 松原 | 铜川 | 绥化 | 雄安新区 | 清远 | 沧州 | 张家口 | 滁州 | 临沧 | 沭阳 | 上饶 | 蚌埠 | 阳春 | 徐州 | 宝鸡 | 洛阳 | 昌吉 | 保亭 | 大庆 | 荆州 | 安徽合肥 | 承德 | 海西 | 海门 | 朝阳 | 济南 | 廊坊 | 肥城 | 梅州 | 灌云 | 茂名 | 山南 | 六盘水 | 神农架 | 张北 | 丽江 | 公主岭 | 德阳 | 新乡 | 南平 | 滕州 | 恩施 | 如皋 | 汝州 | 宣城 | 阜阳 | 阿克苏 | 琼中 | 六盘水 | 莱州 | 屯昌 | 招远 | 舟山 | 库尔勒 | 黑河 | 延安 | 嘉善 | 河源 | 榆林 | 馆陶 | 平凉 | 通辽 | 简阳 | 沛县 | 宿迁 | 甘南 | 玉环 | 台南 | 邵阳 | 日喀则 | 日土 | 普洱 | 陇南 | 西藏拉萨 | 白沙 | 黔东南 | 垦利 | 清远 | 威海 | 金华 | 大同 | 鹰潭 | 安顺 | 偃师 | 大庆 | 诸暨 | 迪庆 | 兴安盟 | 沭阳 | 台北 | 鄂州 | 滨州 | 揭阳 | 保亭 | 黑龙江哈尔滨 | 吐鲁番 |