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();
    }
}
相关推荐
淼淼7638 分钟前
安装jdk1.8
java·开发语言
毕设源码-朱学姐28 分钟前
【开题答辩全过程】以 高校食堂餐饮管理系统的设计与实现为例,包含答辩的问题和答案
java
过期动态31 分钟前
Java开发中的@EnableWebMvc注解和WebMvcConfigurer接口
java·开发语言·spring boot·spring·tomcat·maven·idea
摇滚侠32 分钟前
IDEA 定义返回值快捷键
java·ide·intellij-idea
毕设源码-郭学长34 分钟前
【开题答辩全过程】以 高校考勤管理系统为例,包含答辩的问题和答案
java·eclipse
A懿轩A1 小时前
【Maven 构建工具】从零到上手 Maven:安装配置 + IDEA 集成 + 第一个项目(保姆级教程)
java·maven·intellij-idea
野犬寒鸦1 小时前
从零起步学习并发编程 || 第一章:初步认识进程与线程
java·服务器·后端·学习
我爱娃哈哈1 小时前
SpringBoot + Flowable + 自定义节点:可视化工作流引擎,支持请假、报销、审批全场景
java·spring boot·后端
XiaoFan0122 小时前
将有向工作流图转为结构树的实现
java·数据结构·决策树
小突突突2 小时前
浅谈Java中的反射
java·开发语言