Netty 快速入门

11 篇文章 2 订阅
11 篇文章 1 订阅

本篇文章主要介绍如何快速学习、认识Netty,你也可以把它理解为 学习介绍快速入门。强烈建议你收藏此篇文章,方便后续查阅。

Netty

netty 是一个基于 NIO 模型,实现的 高性能弹性可拓展性异步事件驱动 网络应用程序框架。你可以使用她快速 开发 稳定灵活客户端服务端 应用。官方介绍请看 here

体系结构

在入手之前,我们先来看看技术的整体架构(不喜欢此节,你可以直接跳过去 [get start])
netty 体系结构 netty 架构图,图片来源于 netty 官网

核心组件

这里会列出netty核心组件,当然由于篇幅问题不会做过多讲解

ByteBuf

io.netty.buffer.ByteBuf 是 netty 自定义的二进制数据存储组件,功能类似 java.nio.ByteBuffer,但是它更加简化用户的使用。

readerIndex & writerIndex

如图所示,ByteBuf 定义了readerIndex & writerIndex 方便我们对ByteBuf读取与写入。 image.png

CompositeByteBuf

CompositeByteBuf 是虚拟的buffer,将多个buffer展现为一个简单合并的buffer。这个在多Buffer需要合成一个Buffer情况下使用时(减少内存拷贝)非常实用。

Channel

io.netty.channel 连接到网络套接字或能够进行读、写、连接和绑定等I/O操作的组件。

常用实现类

  1. NioSocketChannel 客户端 NIO selector 实现
  2. NioServerSocketChannel 服务端 NIO selector 实现

ChannelPipeline

io.netty.channel.ChannelPipeline 责任链( ChannelHandler List)模式设计,用于处理或拦截Channel的入站事件和出站操作。处理顺序如下:

ChannelOutboundHandler & ChannelInboundHandler

ChannelHandler

io.netty.channel.ChannelHandler IO事件处理器,这是我们使用最频繁的接口,为了实现我们自己的业务逻辑我们必须向pipeline中添加自己的处理器。

ChannelHandler 入站 & 出站处理

  1. ChannelInboundHandler 入站处理,在使用过程中一般使用 ChannelInboundHandlerAdapter 适配类
  2. ChannelOutboundHandler 出站处理,在使用过程中一般使用 ChannelOutboundHandlerAdapter 适配类

EventLoop

io.netty.channel.EventLoop 负责处理一个或者多个 Channel,每一个EventLoop都会绑定一个 Thread
我们常用的是 NioEventLoopGroup,其是 EventLoopGroup 实现类,NIO 模型中的 EventLoop集合。

Getting Started

终于到这一节了,这一小节会写一个简单的DEMO。相关说明也在代码里加了注释。更加详细说明可以参考 here

Echo Server

public class NettyEchoServerDemo {
    public static void main(String[] args) throws Exception {
        //多线程事件处理器,默认当前核心数 * 2
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //启动类
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)// nio socketchannel
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            //添加应用,数据处理程序 ChannelHandler
                            ch.pipeline().addLast(new EchoChannelHandler());
                        }
                    })
                    //option 用于设置NioServerSocketChannel
                    .option(ChannelOption.SO_BACKLOG, 128)
                    //childOption 用于设置获取到的Channel 也就是 NioSocketChannel
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            // Bind and start to accept incoming connections.
            ChannelFuture f = b.bind(7).sync();
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    //自定义一个 ChannelInboundHandler 
    public static class EchoChannelHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            ctx.write(msg);
            ctx.flush();
        }
    }
}
复制代码

Echo Client

public class NettyEchoClientDemo {
    public static void main(String[] args) throws Exception {
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //client 启动类
            Bootstrap b = new Bootstrap();
            b.group(workerGroup)
                    //SocketChannel
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() { // (4)
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            //自定义数据处理程序 ChannelHandler
                            ch.pipeline().addLast(new EchoChannelHandler());
                        }
                    })
                    .option(ChannelOption.SO_KEEPALIVE, true);
            //建立连接
            ChannelFuture f = b.connect("127.0.0.1",7).syncUninterruptibly(); // (7)
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
        }
    }
    //自定义 ChannelInboundHandler
    public static class EchoChannelHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            System.out.println(((ByteBuf)msg).toString(CharsetUtil.UTF_8));
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            //与服务端交互
            String name = bufferedReader.readLine();
            System.out.println(name);
            ctx.writeAndFlush(Unpooled.copiedBuffer(name.getBytes()));
        }

        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            super.channelActive(ctx);
            //首次出发,发送消息给服务端 这里需要传 ByteBuf
            ChannelFuture c = ctx.writeAndFlush(Unpooled.copiedBuffer("message".getBytes()));
            if(!c.isSuccess()){
                System.out.println(c.cause());
            }
        }
    }
}
复制代码

感谢


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值