Netty—基本组件

netty中组件主要包括Channel、EventLoop、ChannelFuture、ChannelHandler、ChannelPipeline等。

# Channel、EventLoop、ChannelFuture

Channel---Socket
EventLoop---控制流、多线程处理、并发
定义了netty的核心抽象,用于处理连接的生命周期中所发生的事件
ChannelFuture---异步通知

# Channel接口层次

  1. EmbeddedChannel
  2. LocalServerChannel
  3. NioDatagramChannel
  4. NioSctpChannel
  5. NioSocketChannel

# EventLoop

  1. 一个EventLoopGroup中包含了一个或者多个EventLoop;
  2. 一个EventLoop在它的生命周期内只和一个Thread绑定。
  3. 所有由EventLoop处理的I/O事件都将在专有的Thread上被处理。
  4. 一个Channel在它的生命周期内只注册一个或者多个Channel。
  5. 一个EventLoop可以会被分配给一个或者多个Channel。

# ChannelHandler、ChannelPipeline

# ChannelHandler

ChannelHandler是处理入站和出站的事件、数据的应用程序逻辑容器。其中ChannelInBoundHandler相当于接收入站事件和数据。当你要给连接的客户端响应时,也可以从ChannelInBoundHandler中冲刷数据。

# 自定义ChannelHandler时会用的适配器类

  • ChannelHandlerAdapter
  • ChannelInboundHandlerAdapter
  • ChannelOutboundHandlerAdapter
  • ChannelDuplexHandler

# ChannelPipeline

ChannelPipeline为ChannelHandler链提供容器,当Channel被穿件时,会自动的被分配到它的专属ChannelPipeline中。其中ChannelHandler的执行顺序是由它们被添加的顺序所决定的。

实现代码

  • Server
    public void start() throws InterruptedException {
        final EchoServerHandler serverHandler = new EchoServerHandler();
        //创建EventLoopGroup,异步通知消息
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(group)
                    //指定nio-Channel(Socket)来传输小心
                    .channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(port))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            socketChannel.pipeline().addLast(serverHandler);
                        }
                    });
            //异步绑定服务器,调用sync知道sync方法直到成功绑定
            ChannelFuture future = bootstrap.bind().sync();
            //获取Channel的CloseFuture,并且阻塞当前线程知道他完成
            future.channel().closeFuture().sync();

        } finally {
            group.shutdownGracefully().sync();
        }
    }
  • Client
public void start()
            throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .remoteAddress(new InetSocketAddress(host, port))
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new EchoClientHandler());
                        }
                    });
            //连接到远程节点,阻塞等待直到连接完成
            ChannelFuture f = b.connect().sync();
            //阻塞直到channel关闭
            f.channel().closeFuture().sync();
        } finally {
            //关闭连接并且释放所有资源
            group.shutdownGracefully().sync();
        }
    }

# Netty中发送消息的两种方法

  • ChannelHandler ChannelHandler会导致消息从消息从ChannelPipeline的尾端开始流动。
  • ChannelHandlerContext ChannelHandlerContext会导致消息从ChannelPipeline中的下一个ChannelHandler开始流动。

# 实现

# ClientHandler

@ChannelHandler.Sharable
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //通知channel是活跃状态时发送一条消息
        ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!", CharsetUtil.UTF_8));
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
        //记录已经接受消息的转发
        System.out.println("Client received: " + byteBuf.toString(CharsetUtil.UTF_8));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //发生异常记录并且关闭channel
        cause.printStackTrace();
        ctx.close();
    }
}

# ServerHandler

/**
 * @ChannelHandler.Sharable 一个Channel-Handler可以被多个Channel共享
 */
@ChannelHandler.Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
    /**
     * 对于每个传入的消息都要处理调用,将受到的消息写给发送者,而不冲刷出站消息,从socket中读取消息
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf) msg;
        System.out.println("Server received" + byteBuf.toString(CharsetUtil.UTF_8));
        ctx.write(byteBuf);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
                .addListener(ChannelFutureListener.CLOSE);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Netty源码阅读入门实战(二)-基本组件

    NioEventLoopGroup 是一个处理 I/O 操作的多线程事件循环。Netty 为不同类型传输提供各种 EventLoopGroup 实现。

    JavaEdge
  • 【死磕Netty】-----Netty的核心组件

    原文出处http://cmsblogs.com/ 『chenssy』 转载请注明原创出处,谢谢! 在第一篇博客中(【死磕Netty】-----NIO基础详解),...

    用户1655470
  • Netty in Action ——— Netty的组件和设计

    tomas家的小拨浪鼓
  • Vue 组件(一):组件的基本使用

    组件实际上是可以复用的 Vue 实例,它们与 new Vue 接收相同的选项,例如 data、computed、methods 以及生命周期钩子等。 何谓复用?...

    Chor
  • Netty组件源码分析

    深入理解Netty原理之前,先来了解下Netty的核心组件工作原理,通过一个简单的Netty服务程序示例我们可以了解到Netty的核心组件主要有启动类与事件轮询...

    keithl
  • Netty组件之Channel注册

    本文将分析EventLoopGroup初始化、EventLoop的选择策略以及Channel是如何通过EventLoop注册到Selector上的。

    瓜农老梁
  • Docker 组件基本介绍

    供用户使用的命令行工具,负责请求 docker API 与 dockerd 交互,使得用户可以便捷友好的操作 docker。

    我是阳明
  • Flutter开发-基本组件

    用Flutter开发主要的优势就在于UI层的构建,说到界面设计给出的尺寸的单位和开发的单位不一致,那么我们就要获取设备的宽度

    剑行者
  • vue 组件基本使用

    组件是可复用的 Vue 实例,且带有一个名字。把这个组件作为自定义元素来使用。组件的好处是写一次可以进行任意次数的复用

    章鱼喵
  • Netty组件之Channel初始化

    继上文分析Channel实例化流程后,本文通过分析Channel的初始化流程。旨在从整体上厘清DefaultChannelPipeline、ChannelHan...

    瓜农老梁
  • Netty组件之Channel实例化

    Channel建立连接通道,封装了I/O的基本操作。那Channel在Netty中的实例化流程是怎么样的呢?

    瓜农老梁
  • rest_framework框架的基本组件

    阿强Wwlt
  • Netty的基本架构详解

    上一节课我们对Netty有了一个初步的认识,这一节课我们会一起俯瞰整个Netty的脉络,以便于对Netty的架构原理有一个整体的认知!下图是Netty的主要架构...

    止术
  • 《Ext JS模板与组件基本框架图----组件》

    本节主要从七个方面讲解组件,组件时什么,它的作用,它的构架,以及怎么创建和周期还有常见的配置项,属性方法和事件以及其层级是什么都进行整理,希望对大家有帮助。

    yaohong
  • 45 张图深度解析 Netty 架构与原理

    接下来我们会学习一个 Netty 系列教程,Netty 系列由「架构与原理」,「源码」,「架构」三部分组成,今天我们先来看看第一部分:Netty 架构与原理初探...

    kunge
  • Android界面组件基本用法

    文本框(TextView)不允许用户编辑文本内容,而编辑框(EditText)允许用户编辑文本内容

    提莫队长
  • kubernetes的基本概念和组件

    Kubernetes 是一个跨主机集群的 开源的容器调度平台,它可以自动化应用容器的部署、扩展和操作 , 提供以容器为中心的基础架构。

    极客运维圈
  • 互联网大厂Java面试题——Netty 面试题解析

    Netty 是一款基于 NIO(Nonblocking I/O,非阻塞IO)开发的网络通信框架,对比于 BIO(Blocking I/O,阻塞IO),他的并发性...

    Java架构技术
  • netty系列之:netty架构概述

    Netty为什么这么优秀,它在JDK本身的NIO基础上又做了什么改进呢?它的架构和工作流程如何呢?请走进今天的netty系列文章之:netty架构概述。

    程序那些事

扫码关注云+社区

领取腾讯云代金券