6.netty集成Protobuf序列化框架

来源:互联网 发布:软件测试工程师的出路 编辑:程序博客网 时间:2024/05/29 04:44

1.介绍

Protobuf是一个灵活高效、结构化的数据序列化框架,支持跨语言。

2.Protobuf开发环境

下载安装包windows下直接进入exe文件夹下面使用


创建proto文件:

person.proto:文件内容如下,这个文件用来配置我们需要序列化的对象以及属性。这个文件就是跨语言的关键option java_package = "com.tyf.netty";  option java_outer_classname="PersonProtos";    message person {    required string name = 1;    required int32 id = 2;  }
使用命令通过proto文件生成java工具类。当然使用其他语言的命令可以生成其他语言的工具类

生成了一个PersonProtos.java文件这个类是我们要序列化的person对象的一个工具类

接下来我们使用这java文件整合netty来使用


3.netty实现

刚刚生成的PersonProtos这个类中包含一个person内部类就是我们要持久化的类,还包含一些其他的方法用来build生成person对象然后序列化操作等

使用这个工具类需要的依赖

<!-- protobuf依赖 --><dependency>    <groupId>com.google.protobuf</groupId>    <artifactId>protobuf-java</artifactId>    <version>3.4.0</version></dependency>

server

设置proto编码解码器。直接打印msg可以看到对象信息

package com.tyf.netty;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelHandlerAdapter;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelOption;import io.netty.channel.ChannelHandler.Sharable;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.DelimiterBasedFrameDecoder;import io.netty.handler.codec.FixedLengthFrameDecoder;import io.netty.handler.codec.LengthFieldBasedFrameDecoder;import io.netty.handler.codec.LengthFieldPrepender;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.codec.string.StringDecoder;@Sharablepublic class MyServerHandler extends ChannelHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg)  throws Exception{//直接将msg转换成person类PersonProtos.person obj = (PersonProtos.person)msg;//打印System.out.println("消息: "+obj.toString());}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {super.exceptionCaught(ctx, cause);}//创建起步程序public static void  main(String [] argsStrings) throws Exception {//配置服务端NIO线程组(boss线程、worker线程)EventLoopGroup bGroup = new NioEventLoopGroup();EventLoopGroup wGroup = new NioEventLoopGroup();//创建启动辅助类ServerBootstrap bootstrap = new ServerBootstrap();bootstrap.group(bGroup, wGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000) .childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel channel) throws Exception {//添加channel.pipeline().addLast("这个主要用来半包处理",new ProtobufVarint32FrameDecoder());channel.pipeline().addLast("使用刚刚生成的java类设置要序列化的具体类",new ProtobufDecoder(PersonProtos.person.getDefaultInstance()));channel.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());channel.pipeline().addLast(new ProtobufEncoder());channel.pipeline().addLast(new MyServerHandler());} });try {//监听本地端口,同步等待监听结果ChannelFuture future = bootstrap.bind(11111).sync();//等待服务端监听端口关闭,优雅退出future.channel().closeFuture().sync();}finally {bGroup.shutdownGracefully();wGroup.shutdownGracefully();} }}


client

设置proto编解码器。使用PersonProtos工具类生成对象并序列化

package com.tyf.netty;import io.netty.bootstrap.Bootstrap;import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelHandlerAdapter;import io.netty.channel.ChannelHandlerContext;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.NioSocketChannel;import io.netty.handler.codec.FixedLengthFrameDecoder;import io.netty.handler.codec.LengthFieldBasedFrameDecoder;import io.netty.handler.codec.LengthFieldPrepender;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.codec.string.StringDecoder;public class MyClientHandler extends ChannelHandlerAdapter {@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {//使用刚刚生成的java文件创建对象PersonProtos.person.Builder builder = PersonProtos.person.newBuilder();//使用build生成五个对象,写入缓冲builder.setName("name1");builder.setId(1);ctx.write(builder.build());builder.setName("name2");builder.setId(2);ctx.write(builder.build());builder.setName("name3");builder.setId(3);ctx.write(builder.build());//flushctx.flush();}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {super.exceptionCaught(ctx, cause);}//创建起步程序public static void  main(String [] argsStrings) throws Exception {//配置客户端端NIO线程组EventLoopGroup bGroup = new NioEventLoopGroup();//创建客户端启动辅助类Bootstrap bootstrap = new Bootstrap();bootstrap.group(bGroup).  channel(NioSocketChannel.class).  option(ChannelOption.TCP_NODELAY, true).  option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000).  handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel channel) throws Exception {//添加channel.pipeline().addLast("这个主要用来半包处理",new ProtobufVarint32FrameDecoder());channel.pipeline().addLast("使用刚刚生成的java类设置要序列化的具体类",new ProtobufDecoder(PersonProtos.person.getDefaultInstance()));channel.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());channel.pipeline().addLast(new ProtobufEncoder());channel.pipeline().addLast(new MyClientHandler());} });//发起异步连接ChannelFuture future = bootstrap.connect("127.0.0.1", 11111).sync();try {//等待客户端链路关闭future.channel().closeFuture().sync();} finally {//优雅退出,释放资源bGroup.shutdownGracefully();} }}

查看server端输出结果:这里不仅实现了对象序列化还提供了半包问题的解决


阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 固始教育 固始房价 固始人才网 固始人口 固始一中 固始首富 固始在线网 固始特产 固始教育网 固始鸡 固始高铁 固始就业网 固始县属于哪个市 河南省固始县 固始鹅块火锅 固始县邮政编码 固始九华山风景区 固始教育在线 固始县外国语中学 河南固始县为什么穷 河南省固始县邮编 固始高铁站申请成功 固始邮政编码 固始县公共资源交易中心 固始县高中成绩查询 固始房产网首页 固守 固安县 固安镇 固安 房 固安 宾馆 固安 别墅 固安 房价 固安县正式划入北京市 固安县属于哪个市 2019固安县保健一条街 固安k2红树湾 固安县廉租房 固安吧 固安房地产信息网 固安属于哪个市