• netty常用代码


    一. Server

    public class TimeServer_argu {
    
        public void bind(int port) throws InterruptedException {
            EventLoopGroup bossGroup = new NioEventLoopGroup();    // 默认开启cpu个数*2个线程
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
                ServerBootstrap server = new ServerBootstrap();
                server.group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class)
                        .option(ChannelOption.SO_BACKLOG, 128)
                        .childOption(ChannelOption.SO_KEEPALIVE, true)
                        .handler(new LoggingHandler(LogLevel.INFO))
                        .childHandler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            public void initChannel(SocketChannel ch) throws Exception {
                                /* LengthFieldBasedFrameDecoder解码器, 负责解码特定格式报文(开头几个字节表示报文长度), 这个报文长度可以是
                                1. 后面真正报文的长度
                                2. 也可以是算上长度字段的报文总长度 (此时补偿字段为负)
                                */
                                // 报文最大长度,长度字段开始位置偏移量,长度字段所占长度,报文长度的补偿值(netty解析报文首部的长度值,用这个值+补偿值是真正报文的长度),真正报文开始位置的偏移量
                                ch.pipeline().addLast("frameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
                                /*
                                LengthFieldPrepender编码器: netty把真正报文转换成Bytebuf发送,这个编码器在Bytebuf的开头加上真正报文的长度
                                 发送方使用这个编码器,接收方就要使用LengthFieldBasedFrameDecoder解码器来解得真正报文
                                 */
                                ch.pipeline().addLast("frameEncoder", new LengthFieldPrepender(4));
                                // 用于序列化反序列化对象
                                //ch.pipeline().addLast("encode", new ObjectEncoder());
                                // ClassResolvers.weakCachingConcurrentResolver(null)通常用于创建weakhashmap缓存classloader,但ocgi动态替换class,不建议缓存classloader,索引传入null
                                //ch.pipeline().addLast("decode", new ObjectDecoder(ClassResolvers.weakCachingConcurrentResolver(null)));
                                ch.pipeline().addLast(new StringDecoder());
                                ch.pipeline().addLast(new EchoServerHandler());
                           }
                        });
    
                ChannelFuture channel = server.bind(port).sync();
                channel.channel().closeFuture().sync();
             } finally {
                workerGroup.shutdownGracefully();
                bossGroup.shutdownGracefully();
            }
        }
    
        private class EchoServerHandler extends ChannelHandlerAdapter {
            @Override
            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                String str = (String) msg;
                System.out.println("recieve:"+str);
                str = new StringBuilder().append("server recieve ").toString();
                ByteBuf byteBuf = Unpooled.copiedBuffer(str.getBytes());
                ctx.writeAndFlush(byteBuf);
            }
    
            @Override
            public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
                cause.printStackTrace();
                ctx.close();
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            new TimeServer_argu().bind(8011);
        }
    }
    

    二. Client

    public class TimeClient_argu {
        private static Logger logger = LoggerFactory.getLogger("timeclient-argu");
    
        public static void main(String[] args) {
            new TimeClient_argu().connect(8011,"localhost");
        }
    
        public void connect(int port,String host){
            EventLoopGroup group = new NioEventLoopGroup();
            try{
                Bootstrap bs = new Bootstrap();
                bs.group(group).channel(NioSocketChannel.class)
                        .option(ChannelOption.TCP_NODELAY,true)
                        .handler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            protected void initChannel(SocketChannel ch) throws Exception { // netty自动识别编码器和解码器放到输入和读取阶段
                                ch.pipeline().addLast("frameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
                                ch.pipeline().addLast("frameEncoder", new LengthFieldPrepender(4));
                                ch.pipeline().addLast(new StringDecoder());
                                ch.pipeline().addLast(new EchoClientHandler());   // 打印回显信息
                            }
                        });
                //发起异步操作链接
                ChannelFuture f = bs.connect(host,port).sync();
                f.awaitUninterruptibly(10, TimeUnit.SECONDS);
                if (!f.isSuccess()) {   // 连接不成功记录错误日志
                    logger.error(f.cause().getMessage());
                } else {
                    f.channel().writeAndFlush(Unpooled.copiedBuffer("query time".getBytes()));
                    f.channel().closeFuture().sync();
                }
                f.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                group.shutdownGracefully();
            }
        }
    
        private class EchoClientHandler extends ChannelHandlerAdapter {
            private int counter;
            // 发出的请求报文必须带有"
    "或"
    ",否则服务端的LineBasedFrameDecoder无法解析
            private byte[] req = ("query time").getBytes();
    
            @Override
            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                String body = (String) msg;
                System.out.println("Now : "+ body + "the counter is "+ ++counter);
            }
    
    
            /*@Override
               链接成功后自动发送消息
            public void channelActive(ChannelHandlerContext ctx) throws Exception {
                ByteBuf msg = null;
                for (int i = 0; i < 10; i++) {
                    msg = Unpooled.buffer(req.length);  // 创建指定长度的buf
                    msg.writeBytes(req);
                    ctx.writeAndFlush(msg);
                }
            }*/
    
            @Override
            public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
                cause.printStackTrace();
                ctx.close();
            }
        }
    
    }
    
    
  • 相关阅读:
    SpringBoot 之 静态资源路径、显示首页、错误页
    微擎框架的缓存机制实现源码解读
    SpringBoot 之 多环境切换
    SpringBoot 之 JSR303 数据校验
    CSS——NO.6(盒模型)
    CSS——NO.5(格式化排版)
    CSS——NO.4(继承、层叠、特殊性、重要性)
    CSS——NO.3(CSS选择器)
    CSS——NO.2(CSS样式的基本知识)
    CSS——NO.1(初识CSS)
  • 原文地址:https://www.cnblogs.com/72808ljup/p/5325863.html
Copyright © 2020-2023  润新知