spring boot 集成netty,及其一些基本概念

一、基本概念

1、channel:通道,入站或者出站数据的载体

2、ChannelHandler:通道处理器,业务逻辑写在这里面,netty 5版本将入战和出站合并成了ChannelHandler

3、ChannelPipeline:通道里的管道,是一个或者多个ChannelHandler链的容器,当channel被创建时,会为该Channel自动分配一个ChannelPipeline,ChannelPipeline中可以放多个ChannelHandler。

4、ChannelHandlerContext:通道处理器上下文,代表了ChannelHandler和ChannelPipeline的关联关系,每当有ChannelHandler被添加到ChannelPipeline时就会创建一个ChannelHandlerContext。ChannelHandlerContext的主要功能是管理它所关联的ChannelHandler和在同一个ChannelPipeline中其他的ChannelHandler之间的交互。

5、ChannelHandlerAdapter:通道处理器的适配器,提供了入站和出站ChannelHandler的基本实现。

6、EventLoop与EventLoopGroup:称为事件循环,用来运行连着周期内发生的事件的。EventLoopGroup为每个新创建的Channel分配一个EventLoop。多个Channel可以共享一个EventLoop。

7、SimpleChannelInboundHandler:可以用来接收解码消息,无需手动释放资源。

8、引导:作用是创建Channel组装成可运行的程序。分为客户端引导和服务端引导。客户端引导:为客户端应用程序创建Channel当调用bind()或者connect()方法时就会创建一个Channel。服务器引导:当bind()方法被调用时会创建一个ServerChannel,当有客户端连接并且服务器端接受时,ServerChannel会创建相应的Channel进行通信。

9、ChannelInitializer:通道Channel初始化时调用。

10、入站和出站:入站是指数据从网络层流向你的应用程序,出战是指数据从应用程序流向网络层。在ChannelPipeline的流向,入站是从头到尾,出站是从尾流向头部。

11、注意:ChannelHandler的实现类,如果被标记为@Sharable,则代码该处理器可以被添加到多个ChannelPipeline中去。

二、搭建一个简单的客户端和服务端

1、安装依赖

复制代码
<dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>5.0.0.Alpha2</version>
</dependency>

2、客户端

2.1 新建处理器类:EchoClientHandler

复制代码
@ChannelHandler.Sharable
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {

    @Override
    public void channelActive(ChannelHandlerContext ctx){
        ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!", CharsetUtil.UTF_8));
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg){
        ByteBuf in = (ByteBuf) msg;
        System.out.println("Client received: " + in.toString(CharsetUtil.UTF_8));
    }

    @Override
    protected void messageReceived(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {

    }

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

2.2 新建客户端引导

复制代码
public class EchoClient {
    private final String host;

    private final int port;

    public EchoClient(String host, int port) {
        this.host = host;
        this.port = port;
    }


    public void start() throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    .remoteAddress(new InetSocketAddress(host, port))
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new EchoClientHandler());
                        }
                    });

            ChannelFuture future = bootstrap.connect().sync();
            future.channel().closeFuture().sync();
        }finally {
            group.shutdownGracefully().sync();
        }
    }

    public static void main(String[] args) throws Exception {
        new EchoClient("127.0.0.1", 2221).start();
    }

}

3、服务器端

3.1 新建服务器端ChannelHandler

复制代码
@ChannelHandler.Sharable
//@ChannelHandler.Sharable
public class EchoServerHandler extends SimpleChannelInboundHandler {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg){

        ByteBuf in = (ByteBuf) msg;
        System.out.println("Server received: " + in.toString(CharsetUtil.UTF_8));
        ctx.write(in);
    }

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

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

    @Override
    protected void messageReceived(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {

    }
}

3.2 新建服务器端引导

复制代码
public class EchoServer {
    private final int port;

    public EchoServer(int port) {
        this.port = port;
    }

    public void start() throws Exception {
        final EchoServerHandler serverHandler = new EchoServerHandler();
        EventLoopGroup group = new NioEventLoopGroup();

        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(group)
                    .channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(port))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(serverHandler);
                        }
                    });
            System.out.println("监听端口");
            ChannelFuture f=b.bind().sync();
            System.out.println("服务端关闭");
            f.channel().closeFuture().sync();
        }finally {
            group.shutdownGracefully().sync();
        }
    }

    public static void main(String[] args) throws Exception {
        new EchoServer(2221).start();
    }
}
相关推荐
FreeBuf_2 小时前
微软Copilot被用于窃取OAuth令牌,AI Agent成为攻击者帮凶
人工智能·microsoft·copilot
计算机学长felix3 小时前
基于SpringBoot的“面向校园的助力跑腿系统”的设计与实现(源码+数据库+文档+PPT)
数据库·spring boot·后端
fat house cat_3 小时前
【netty】基于主从Reactor多线程模型|如何解决粘包拆包问题|零拷贝
java·服务器·网络·netty
青云交3 小时前
Java 大视界 -- Java 大数据在智能教育学习社区互动模式创新与用户活跃度提升中的应用(426)
java·大数据·学习·flink 实时计算·智能教育社区·互动模式创新·用户活跃度
李少兄3 小时前
HTML 表单控件
前端·microsoft·html
神奇的海马体3 小时前
Tomcat隐藏版本号
java·tomcat
拜见老天師3 小时前
使用mybatis-plus,实现将排序时,字段值为NULL的数据排在最后
java·mybatis
java水泥工4 小时前
课程答疑系统|基于SpringBoot和Vue的课程答疑系统(源码+数据库+文档)
spring boot·vue·计算机毕业设计·java毕业设计·大学生毕业设计·课程答疑系统
应茶茶4 小时前
C++11 核心新特性:从语法重构到工程化实践
java·开发语言·c++
Reggie_L4 小时前
RabbitMQ -- 高级特性
java·rabbitmq·java-rabbitmq