• Netty 学习笔记


    3 netty 吸取经验快速高效的的事件驱动的框架,可伸缩性和高性能
    4 第一次写不是helloworld而是discard 服务,就是没相应的。
    
    read方法原来是客户端的
    两个方法 读和 异常处理
     接受数据,静默处理 用 msg.release();
     有异常了直接关闭管道链接
    package io.netty.example.discard;
    
    import io.netty.buffer.ByteBuf;
    
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    
    /**
     * Handles a server-side channel.
     */
    public class DiscardServerHandler extends ChannelInboundHandlerAdapter { // (1)
    
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) { // (2)
            // Discard the received data silently.
            ((ByteBuf) msg).release(); // (3)
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)
            // Close the connection when an exception is raised.
            cause.printStackTrace();
            ctx.close();
        }
    }
    
    其实在正常的处理中都哦是这样的 操作
    在读消息的时候
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf in = (ByteBuf) msg;
        try {
            while (in.isReadable()) { // (1)
                System.out.print((char) in.readByte());
                System.out.flush();
            }
        } finally {
            ReferenceCountUtil.release(msg); // (2)
        }
    }
    (2)中基本等价于 in.release() 
    (1)循环效率低,可改为,不明白为啥,没啥区别
    为:System.out.println(in.toString(io.netty.util.CharsetUtil.US_ASCII))
    
    
    其实 最主要的main方法调用
    package io.netty.example.discard;
        
    import io.netty.bootstrap.ServerBootstrap;
    
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelOption;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
        
    /**
     * Discards any incoming data.
     */
    public class DiscardServer {
        
        private int port;
        
        public DiscardServer(int port) {
            this.port = port;
        }
        
        public void run() throws Exception {
            EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
                ServerBootstrap b = new ServerBootstrap(); // (2)
                b.group(bossGroup, workerGroup)
                 .channel(NioServerSocketChannel.class) // (3)  制定了nioserver
                 .childHandler(new ChannelInitializer<SocketChannel>() { // (4) 指定了初始化类
                     @Override
                     public void initChannel(SocketChannel ch) throws Exception {
                         ch.pipeline().addLast(new DiscardServerHandler());
                     }
                 })
                 .option(ChannelOption.SO_BACKLOG, 128)          // (5)
                 .childOption(ChannelOption.SO_KEEPALIVE, true); // (6)
        
                // Bind and start to accept incoming connections.
                ChannelFuture f = b.bind(port).sync(); // (7)
        
                // Wait until the server socket is closed.
                // In this example, this does not happen, but you can do that to gracefully
                // shut down your server.
                f.channel().closeFuture().sync();
            } finally {
                workerGroup.shutdownGracefully();
                bossGroup.shutdownGracefully();
            }
        }
        
        public static void main(String[] args) throws Exception {
            int port = 8080;
            if (args.length > 0) {
                port = Integer.parseInt(args[0]);
            }
    
            new DiscardServer(port).run();
        }
    }
    
    其中 NioEventLoopGroup 处理多线程,有boss和worker的概念
    ServerBootstrap 是个帮助类,可用channel来代替,先都不要动
    用于设置服务器类
    第5个标注 表示管道参数,可以查看其他的参数ChannelOption。编译器来提升
    
    在上面实际的handler中写 上面的
    
    
    5 上面是没有回复的,这次写个有回复的server,收到后写回??
    @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            ctx.write(msg); // (1)
            ctx.flush(); // (2)
        }
    
    6 再写time server,time是一个协议 等等
    
    9 默认用ByteBuf,可以用pojo来代替
    decoder 修改
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
        if (in.readableBytes() < 4) {
            return;
        }
    
        out.add(new UnixTime(in.readUnsignedInt()));
    }
    timeclienthandler也修改类型
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        UnixTime m = (UnixTime) msg;
        System.out.println(m);
        ctx.close();
    }
    
    也可以修改服务端 timeserverhandler
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        ChannelFuture f = ctx.writeAndFlush(new UnixTime());
        f.addListener(ChannelFutureListener.CLOSE);
    }
    现在没有处理的就是 encoder部分,修改为
    package io.netty.example.time;
    
    public class TimeEncoder extends ChannelOutboundHandlerAdapter {
        @Override
        public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
            UnixTime m = (UnixTime) msg;
            ByteBuf encoded = ctx.alloc().buffer(4);
            encoded.writeInt((int)m.value());
            ctx.write(encoded, promise); // (1)
        }
    }
    总结了一堆原理后,修改 timeencoder 他的继承就好了
    public class TimeEncoder extends MessageToByteEncoder<UnixTime> {
        @Override
        protected void encode(ChannelHandlerContext ctx, UnixTime msg, ByteBuf out) {
            out.writeInt((int)msg.value());
        }
    }
    
    10 netty的关闭
  • 相关阅读:
    总结(1)--- 数据库
    在路上---学习篇(一)Python 数据结构和算法 (4) --希尔排序、归并排序
    在路上---学习篇(一)Python 数据结构和算法 (3) --快速排序
    在路上---学习篇(一)Python 数据结构和算法 (2) -- 冒泡排序、选择排序、插入排序
    javascript观察者模式
    es6对象的扩展
    es6数组的扩展
    vue全局API
    javascript原型链
    简单工厂,工厂方法模式
  • 原文地址:https://www.cnblogs.com/genestart/p/11355715.html
Copyright © 2020-2023  润新知