Netty protobuf解析2-官方方法解析

来源:互联网 发布:算法工程师的数学工具 编辑:程序博客网 时间:2024/06/07 01:08

关键代码如下


 p.addLast(new ProtobufVarint32FrameDecoder());// 解码1. 根据byte 的头长度 来 分割                     p.addLast(new ProtobufDecoder( Msg.Person.getDefaultInstance()));  //解码2。  byte 转化为 实体类                     p.addLast(new ProtobufVarint32LengthFieldPrepender()); //编码3. byte 数组头加上 ,实体类的长度                     p.addLast(new ProtobufEncoder());   //编码2.  Msg.Person 实体 转化为 byte数组                                      p.addLast( new EchoServerHandler()); //编码1. 写入  Msg.Person 实体



客户端,如下

package core.echo.offiDecoder;/* * zenglx created  at  2017/5/15 11:28 */import static java.lang.Thread.sleep;import io.netty.bootstrap.Bootstrap;import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.Channel;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelOutboundHandlerAdapter;import io.netty.channel.ChannelPipeline;import io.netty.channel.ChannelPromise;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioSocketChannel;import io.netty.handler.codec.protobuf.ProtobufDecoder;import io.netty.handler.codec.protobuf.ProtobufEncoder;import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;import java.io.IOException;import java.util.logging.Logger;public  class EchoPOJOClient {    public  void connect() throws InterruptedException, IOException {        String host="127.0.0.1";        int port=8081;        // Configure the client.        EventLoopGroup workerGroup = new NioEventLoopGroup();        try {            Bootstrap b = new Bootstrap();            b.group(workerGroup).channel(NioSocketChannel.class);            b.handler(new ChannelInitializer<SocketChannel>() {                public void initChannel(SocketChannel ch) throws Exception {                ChannelPipeline p=ch.pipeline();                    p.addLast(new ProtobufVarint32FrameDecoder());// 解码1. 根据byte 的头长度 来 分割                    p.addLast(new ProtobufDecoder( Msg.Person.getDefaultInstance()));  //解码2。  byte 转化为 实体类                    p.addLast(new ProtobufVarint32LengthFieldPrepender()); //编码3. byte 数组头加上 ,实体类的长度                    p.addLast(new ProtobufEncoder());   //编码2.  Msg.Person 实体 转化为 byte数组                                    p.addLast( new EchoClientHander()); //编码1. 写入  Msg.Person 实体                }            });            ChannelFuture cf=b.connect(host,port).sync();            sendTOServer(cf.channel());            // Wait until the server socket is closed.        } finally {            // Shut down all event loops to terminate all threads.            workerGroup.shutdownGracefully();        }    }    private static final Logger logger = Logger.getLogger(EchoPOJOClient.class.getName());    public static void main(String str[]) throws InterruptedException, IOException {        new EchoPOJOClient().connect();        logger.info("client ........started");    }    public void sendTOServer(Channel ch) throws InterruptedException, IOException {        // 按照定义的数据结构,创建一个Person          Msg.Person.Builder personBuilder = Msg.Person.newBuilder();        personBuilder.setId(1);        personBuilder.setName("sdfsdfsf");        personBuilder.setEmail("xxg@163.com");        Msg.Person msg = personBuilder.build();        int i=0;        //5s 发送一次        for (;i<Integer.MAX_VALUE;) {        i++;        personBuilder.setId(i);        msg = personBuilder.build();            sleep(5000);//            ch.writeAndFlush(msg);        }    }    //业务处理handler    class EchoClientHander extends ChannelInboundHandlerAdapter {        Logger logger = Logger.getLogger(EchoClientHander.class.getName());        @Override        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {            logger.info(msg.toString());        }    }    //   POJO 转化为   bytebuf,  处理用户事件 所以继承ChannelOutboundHandlerAdapter    class MsgEncoder extends ChannelOutboundHandlerAdapter {        Logger logger=Logger.getLogger(EchoClientHander.class.getName());        @Override        public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {            Msg.Person  p=( Msg.Person)msg;            ByteBuf byteBuf= Unpooled.buffer();            byteBuf.writeBytes(p.toByteArray());            byteBuf.writeBytes("\r\n".getBytes()); //加上换行符            logger.info("MsgEncoder.................");            ctx.write(byteBuf,promise);// 需要再次写入        }    }}



服务端,


package core.echo.offiDecoder;import io.netty.bootstrap.ServerBootstrap;import io.netty.buffer.ByteBuf;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioServerSocketChannel;import io.netty.handler.codec.protobuf.ProtobufDecoder;import io.netty.handler.codec.protobuf.ProtobufEncoder;import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;import io.netty.handler.logging.LogLevel;import io.netty.handler.logging.LoggingHandler;import java.util.logging.Logger;public class EchoPOJOServer {    public void listen() throws Exception {        int port=8081;        // Configure the server.         EventLoopGroup bossGroup = new NioEventLoopGroup();        EventLoopGroup workerGroup = new NioEventLoopGroup();        try {            ServerBootstrap b = new ServerBootstrap();            b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class);            b.handler(new LoggingHandler(LogLevel.DEBUG));            b.childHandler(new ChannelInitializer<SocketChannel>() {                public void initChannel(SocketChannel ch) throws Exception {                ChannelPipeline p=ch.pipeline();                                 p.addLast(new ProtobufVarint32FrameDecoder());// 解码1. 根据byte 的头长度 来 分割                     p.addLast(new ProtobufDecoder( Msg.Person.getDefaultInstance()));  //解码2。  byte 转化为 实体类                     p.addLast(new ProtobufVarint32LengthFieldPrepender()); //编码3. byte 数组头加上 ,实体类的长度                     p.addLast(new ProtobufEncoder());   //编码2.  Msg.Person 实体 转化为 byte数组                                      p.addLast( new EchoServerHandler()); //编码1. 写入  Msg.Person 实体                }            });            ChannelFuture cf=b.bind(port).sync();            cf.channel().closeFuture().sync();            // Wait until the server socket is closed.        } finally {            // Shut down all event loops to terminate all threads.             bossGroup.shutdownGracefully();            workerGroup.shutdownGracefully();        }    }    private static final Logger logger = Logger.getLogger(EchoPOJOServer.class.getName());    public static void main(String str[]) throws Exception {        new EchoPOJOServer().listen();        logger.info("server ........started");    }      //业务处理handler     class EchoServerHandler extends ChannelInboundHandlerAdapter {        private  final Logger logger = Logger.getLogger(EchoServerHandler.class.getName());        @Override        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {            logger.info("server read......"+msg.toString());        }        @Override        public void channelInactive(ChannelHandlerContext ctx) throws Exception {            logger.info("chanle is closed ");        }    }    //  bytebuf  转化为  POJO ,  处理io 事件,继承ChannelInboundHandlerAdapter    class MsgDecoder extends ChannelInboundHandlerAdapter {        Logger logger=Logger.getLogger(MsgDecoder.class.getName());        @Override        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {            ByteBuf  bytebuf= (ByteBuf) msg;            // bytebuf.array();// 报错 java.lang.UnsupportedOperationException: direct buffer  还没有分析到位            byte [] b=new byte[bytebuf.readableBytes()];            bytebuf.readBytes(b);            Msg.Person xxg2 = Msg.Person.parseFrom(b);            logger.info("MsgDecoder................."+xxg2.toString());            ctx.fireChannelRead(xxg2);        }    }}