Netty入门

官网

https://netty.io/

Netty is an asynchronous event-driven network application framework
for rapid development of maintainable high performance protocol servers & clients.

Netty是一个异步的、基于事件驱动的网络应用框架,用于快速开发可维护、高性能的网络服务器和客户端。

客户端发送,服务端接收案例

// 服务端
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ServerDemo {
    private static final Logger log = LoggerFactory.getLogger(ServerDemo.class);

    public static void main(String[] args) {
        // 启动服务器
        new ServerBootstrap()
                // 设置线程组
                .group(new NioEventLoopGroup())
                // ServerSocketChannel模式选择
                .channel(NioServerSocketChannel.class)
                // worker处理连接
                .childHandler(
//                        通道初始化,添加handler
                        new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
//                        将buffer转为字符串
                        nioSocketChannel.pipeline().addLast(new StringDecoder());
//                        自定义处理器
                        nioSocketChannel.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                            @Override
                            public void channelRead(ChannelHandlerContext ctx,Object msg)throws Exception {
                                log.info(msg.toString());
                            }
                        });
                    }
                })
//                绑定端口
                .bind(8090);
    }
}

// 客户端
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;

public class ClientDemo {
    public static void main(String[] args) throws InterruptedException {
//        启动类
        new Bootstrap()
//                添加eventloop
                .group(new NioEventLoopGroup())
//                选择客户端实现
                .channel(NioSocketChannel.class)
//                添加处理器
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        nioSocketChannel.pipeline().addLast(new StringEncoder());
                    }
                })
                // 连接到服务器
                .connect("localhost",8090)
                // 阻塞方法,直到连接建立
                .sync()
                // 获取连接对象
                .channel()
                // 向服务器发送数据
                .writeAndFlush("微信小程序:马上行计划管理,欢迎体验。");
    }
}

客户端调试idea设置

允许启动多实例
在这里插入图片描述
启用多线程调试,断点处右键
在这里插入图片描述

netty常用组件

EventLoop

本质是一个单线程执行器维护了一个Selector,管理channel。
public interface EventLoop extends OrderedEventExecutor, EventLoopGroup

Channel

建立连接后channel与EventLoop绑定。

Future和Promise

    @Test
    public void testJdkFeature() throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(2);
        Future<Integer> submit = executor.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                log.info("Callable");
                Thread.sleep(1000);
                return 10;
            }
        });
        log.info("执行完成submit");
        log.info("等待结果{}", submit.get());
    }

    @Test
    public void testNettyFeature() throws Exception {
        NioEventLoopGroup group = new NioEventLoopGroup();
        try {
            EventLoop next = group.next();
            io.netty.util.concurrent.Future<Integer> future = next.submit(() -> {
                log.info("Callable");
                Thread.sleep(1000);
                return 20;
            });

            // 使用CountDownLatch等待异步操作完成
            CountDownLatch latch = new CountDownLatch(1);

            future.addListener((GenericFutureListener<io.netty.util.concurrent.Future<? super Integer>>) f -> {
                try {
                    log.info("等待结果{}", f.getNow());
                } finally {
                    latch.countDown();
                }
            });

            log.info("执行完成submit");

            // 等待异步操作完成,设置合理的超时时间
            assertTrue(latch.await(2, TimeUnit.SECONDS));
        } finally {
            group.shutdownGracefully().sync();
        }
    }

    @Test
    public void testNettyPromise() throws Exception{
        EventLoop next = new NioEventLoopGroup().next();
        DefaultPromise<Integer> promise = new DefaultPromise<>(next);
        new Thread(()->{
            log.info("新线程开始");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            promise.setSuccess(30);
        }).start();
        log.debug("等待结束");
        // 等待异步操作完成,设置合理的超时时间
        log.info("计算结果是{}",promise.get());
    }

Handler和Pipline

Pipline相当于一个流水线,而Handler则相当于流水线每一个工序。
Hander分为入站和出栈两种类型。

pipline执行handler数序

public class PiplineDemo {
    static final Logger log = LoggerFactory.getLogger(PiplineDemo.class);

    public static void main(String[] args) {

        // 启动服务器
        new ServerBootstrap()
                // 设置线程组
                .group(new NioEventLoopGroup(),new NioEventLoopGroup())
                // ServerSocketChannel模式选择
                .channel(NioServerSocketChannel.class)
                // worker处理连接,一个channel绑定一个eventloop
                .childHandler(
//                        通道初始化,添加handler
                        new ChannelInitializer<NioSocketChannel>() {
                            @Override
                            protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                                ChannelPipeline pipeline = nioSocketChannel.pipeline();
//                                处理器head->first->second->third->sixth->fifth->fourth->tail
                                pipeline.addLast("first",new ChannelInboundHandlerAdapter(){
                                    public void channelRead(ChannelHandlerContext ctx,Object message) throws Exception {
                                        log.info("first");
                                        super.channelRead(ctx,message);
                                    }
                                });
                                pipeline.addLast("second",new ChannelInboundHandlerAdapter(){
                                    public void channelRead(ChannelHandlerContext ctx,Object message) throws Exception {
                                        log.info("second");
                                        super.channelRead(ctx,message);
                                    }
                                });
                                pipeline.addLast("third",new ChannelInboundHandlerAdapter(){
                                    public void channelRead(ChannelHandlerContext ctx,Object message) throws Exception {
                                        log.info("third");
//                                        super.channelRead(ctx,message);
//                                        使用nioSocketChannel从tail往前走所有的出站处理器
//                                        nioSocketChannel.writeAndFlush(ctx.alloc().buffer().writeBytes("欢迎使用微信小程序马上行计划管理".getBytes()));
//                                        使用ctx从当前位置往前找出站处理器
                                        ctx.writeAndFlush(ctx.alloc().buffer().writeBytes("欢迎使用微信小程序马上行计划管理".getBytes()));
                                    }
                                });
                                pipeline.addLast("fourth",new ChannelOutboundHandlerAdapter(){
                                    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                                        log.info("fourth");
                                        super.write(ctx,msg,promise);
                                    }
                                });
                                pipeline.addLast("fifth",new ChannelOutboundHandlerAdapter(){
                                    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                                        log.info("fifth");
                                        super.write(ctx,msg,promise);
                                    }
                                });
                                pipeline.addLast("sixth",new ChannelOutboundHandlerAdapter(){
                                    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                                        log.info("sixth");
                                        super.write(ctx,msg,promise);
                                    }
                                });
                            }
                        })
//                绑定端口
                .bind(8090);
    }
}

测试handler及顺序

    private static final Logger log = LoggerFactory.getLogger(ClientDemo.class);
    public static void main(String[] args) {
        ChannelInboundHandlerAdapter first=new ChannelInboundHandlerAdapter(){
            public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception {
                log.info("first");
                super.channelRead(ctx,message);
            }
        };
        ChannelInboundHandlerAdapter second=new ChannelInboundHandlerAdapter(){
            public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception {
                log.info("second");
                super.channelRead(ctx,message);
            }
        };
        ChannelOutboundHandlerAdapter fourth=new ChannelOutboundHandlerAdapter(){
            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                log.info("fourth");
                super.write(ctx,msg,promise);
            }
        };
        ChannelOutboundHandlerAdapter fifth=new ChannelOutboundHandlerAdapter(){
            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                log.info("fifth");
                super.write(ctx,msg,promise);
            }
        };
        EmbeddedChannel channel = new EmbeddedChannel(first,second,fourth,fifth);
//        模拟入栈
        channel.writeInbound("欢迎使用微信小程序马上行计划管理".getBytes());
//        模拟出站
        channel.writeOutbound("欢迎使用微信小程序马上行计划管理".getBytes());
    }

ByteBuf

自动扩容,内存管理使用引用计数器法。

        // 堆内存
        ByteBufAllocator.DEFAULT.heapBuffer();
        // 直接内存
        ByteBufAllocator.DEFAULT.directBuffer();

此文技术,助力微信小程序:马上行计划管理。
欢迎体验,微信搜索马上行计划管理,或者扫码
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值