zoukankan      html  css  js  c++  java
  • 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的关闭
  • 相关阅读:
    mybatis映射器${}和#{}的区别
    在list里循环放入map,每次map里的值都不一样,可是放入后再取出来就变成一样的
    tomcat 配置 编码方式后,重新启动 配置还原
    三级联动探索
    Excel导入导出的实现
    Servlet实现文件上传下载
    Java数据类型转换汇总
    mysql8.0.13安装
    cmd中命令能用,vs中不能用解决方案
    yii2获取模块、控制器、方法名
  • 原文地址:https://www.cnblogs.com/genestart/p/11355715.html
Copyright © 2011-2022 走看看