12.Netty入门案例

1.引入Netty依赖

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

2.服务端

public class HelloServer {
    public static void main(String[] args) {

        // 1.启动器,负责组装Netty组件,启动服务器
        new ServerBootstrap()
                // 2.BossEventLoop,WorkerEventLoop(selector,thread),group组
                .group(new NioEventLoopGroup())
                // 3.选择服务器的ServerSocketChannel 实现
                .channel(NioServerSocketChannel.class) // NIO,BIO,OIO
                // 4.Boss负责处理连接,worker(child)负责处理读写,决定了worker(child)能执行哪些操作handler
                .childHandler(
                        // 5. channel代表和客户端进行数据读写的通道 Initializer初始化,负责添加别的handler
                        new ChannelInitializer<NioSocketChannel>() {

                            @Override // 连接建立后被调用
                            protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                                // 6. 添加具体的handler
                                nioSocketChannel.pipeline().addLast(new StringDecoder()); //将ByteBuf 转换为字符串
                                nioSocketChannel.pipeline().addLast(new ChannelInboundHandlerAdapter(){ // 自定义handler
                                    // 读事件
                                    @Override
                                    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                        //打印上一个handler已经处理好的字符串
                                        System.out.println(msg);
                                    }
                                });

                            }
                        })
                // 7. 绑定监听端口
                .bind(8888);

    }
}

第二步中NioEventLoopGroup,会有一个线程不断循环,配合选择器selector,监测accept、read等事件。

当accept事件发生以后,也就是连接建立以后,由某个一EventLoop对象处理,才会去执行第六步中的initChannel方法。

3.客户端

public class HelloClient {

    public static void main(String[] args) throws InterruptedException {
        // 1.启动器,负责组件netty组件,启动客户端
        new Bootstrap()
                // 2. 添加 EventLoop(BossEventLoop,WorkerEventLoop(selector, thread)),group组
               .group(new NioEventLoopGroup())
                // 3. 选择客户端的SocketChannel实现
               .channel(NioSocketChannel.class)
                // 4. 添加处理器
               .handler(
                       // 5. channel代表和客户端进行数据读写的通道 Initializer初始化,负责添加别的handler

                        new ChannelInitializer<NioSocketChannel>() {
                            @Override // 连接建立后被调用
                            protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                                nioSocketChannel.pipeline().addLast(new StringEncoder()); //将String-> ByteBuf
                            }
                        }
                )
                // 6.连接到服务端
                .connect(new InetSocketAddress("localhost", 8888))
                .sync()
                .channel()
                // 7.向服务端发送数据
                .writeAndFlush("hello netty");

    }
}

sync方法是阻塞方法,客户端与服务端连接建立成功才会继续执行。然后服务端的NioEventLoopGroup中的某一个EventLoop就会处理accept事件。

客户端发送了数据writeAndFlush方法后,就会去执行pipeline上的具体的每个handler中的方法,比如会执行StringEncoder Handler,也就是出栈,将String转成ByteBuf对象。

然后服务端的 NioEventLoopGroup中的某一个EventLoop就会处理read事件。

服务端接收到数据,会执行StringDecoder Handler,也就是入栈,将ByteBuf对象转成String对象。再传递给下一个handler,直接将消息打印到控制台。

channel理解为数据通道。

msg理解为流动的数据,最开始输入ByteBuf,经过pipeline加工,会变成其他类型的对象,最后输出有变成ByteBuf对象。

handler理解为数据的处理工序,工序有多道,合在一起就是pipeline,传播给每个handler,handler对自己感兴趣的事件进行处理。handler分为InBound入栈和OutBound出栈两类。

eventLoop理解为处理数据的工人,就是selector和Thread,工人可以管理多个channel的io操作,并且工人一旦负责了某个channel,就要负责到底(绑定)。工人按照pipeline顺序,依次按照handler的代码处理数据(入栈、出栈)。eventLoop就是一个单线程的线程池。

相关推荐

  1. 12.Netty入门案例

    2024-05-11 00:06:03       30 阅读
  2. Netty入门使用

    2024-05-11 00:06:03       48 阅读
  3. 11.Netty简单认识

    2024-05-11 00:06:03       37 阅读
  4. Netty案例-群聊天室实现

    2024-05-11 00:06:03       48 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-11 00:06:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-11 00:06:03       101 阅读
  3. 在Django里面运行非项目文件

    2024-05-11 00:06:03       82 阅读
  4. Python语言-面向对象

    2024-05-11 00:06:03       91 阅读

热门阅读

  1. libevent 梳理

    2024-05-11 00:06:03       27 阅读
  2. golang 随机数演化

    2024-05-11 00:06:03       30 阅读
  3. c++ 线程的激活和休眠

    2024-05-11 00:06:03       32 阅读
  4. PHP 在字符中找出重复次数最多的字符

    2024-05-11 00:06:03       27 阅读
  5. 算法有哪些分类

    2024-05-11 00:06:03       36 阅读
  6. 变量的细节

    2024-05-11 00:06:03       29 阅读
  7. Spring原理分析--获取Environment资源对象

    2024-05-11 00:06:03       28 阅读
  8. 生成式 AI 的发展方向,应当是 Chat 还是 Agent?

    2024-05-11 00:06:03       29 阅读