关键词:
作者:rickiyang
出处:www.cnblogs.com/rickiyang/p/11074232.html
我们来使用Protobuf进行序列化,它和XML,json一样都有自己的语法,xml的后缀是.xml,json文件的后缀是.json,自然Protobuf文件的后缀就是.proto(哈哈,当然不是全称)。
下面我们使用Protobuf来封装一段消息,通过一个案例简单介绍一下它的使用。
首先我们用Protobuf的语法格式来写一段需要序列化的对象,命名格式为:Msg.proto
option java_package = "cn.edu.hust.netty.demo10";
option java_outer_classname = "MessageProto";
message RequestMsg
required bytes msgType = 1;
required string receiveOne = 2;
required string msg = 3;
message ResponseMsg
required bytes msgType = 1;
required string receiveOne = 2;
required string msg = 3;
关于Message.proto中的语法格式,详情大家google一下相关的说明,网上很多介绍,再次简单就上面的语法说明一下:
- option java_package:表示生成的.java文件的包名
- option java_outer_classname:生成的java文件的文件名
- message : 为他的基本类型,如同java中的class一样
字段修饰符:
- required:一个格式良好的消息一定要含有1个这种字段。表示该值是必须要设置的;
- optional:消息格式中该字段可以有0个或1个值(不超过1个)。
- repeated:在一个格式良好的消息中,这种字段可以重复任意多次(包括0次)。重复的值的顺序会被保留。表示该值可以重复,相当于java中的List。
字符类型稍微有些不同:double,float,int32,int64,bool(boolean),string,bytes。稍微有些不同,String,boolean,int有差别。
另外我们看到上面3个字段分别赋值了,这个值是什么意思呢?消息定义中,每个字段都有唯一的一个数字标识符。这些标识符是用来在消息的二进制格式中识别各个字段的,一旦开始使用就不能够再改变。注:[1,15]之内的标识号在编码的时候会占用一个字节。[16,2047]之内的标识号则占用2个字节。所以应该为那些频繁出现的消息元素保留 [1,15]之内的标识号。
关于Protobuf 的语法我们就简单的介绍这么多,更多细节大家自己去查阅文档吧。下面我们开始使用Protobuf 来进行序列化。
首先我们的在工程中引入protobuf的jar包,目前官方版本最高3.2,我们用3.0的吧:
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.0.2</version>
</dependency>
Protobuf的文件已经定义好了,下就需要把它编译成java代码,这里我们的借助到google为我们提供的脚本工具protoc,链接在这里,点击下载这里提供的是protoc-3.0.2。要注意protoc的版本需要和Protobuf的版本对应上,不然不同的版本之间会有一些差异解析可能会有问题。现在知道我们为啥非得选用protobuf3.0.2版本吧,因为我没有找到别的版本的protoc。。。
下载好了我们解压缩然后把刚才写好的Msg.proto文件复制进去。
接着我们进cmd输入如下命令:
主要是第三句命令。如果你输入没有报错的话你的proto文件夹应该会生成一个子文件夹:
进去该文件夹你会看到已经生成了MessageProto.java文件,恭喜你,这时候你已经完成了protobuf序列化文件的生成。然后你把该文件拷贝至工程目录下。
接下来我们用生成的文件去发消息吧。还是老套路服务端和客户端。
服务端:
public class ProtoBufServer
private int port;
public ProtoBufServer(int port)
this.port = port;
public void start()
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workGroup = new NioEventLoopGroup();
ServerBootstrap server = new ServerBootstrap().group(bossGroup,workGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ServerChannelInitializer());
try
ChannelFuture future = server.bind(port).sync();
future.channel().closeFuture().sync();
catch (InterruptedException e)
e.printStackTrace();
finally
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
public static void main(String[] args)
ProtoBufServer server = new ProtoBufServer(7788);
server.start();
服务端Initializer:
public class ServerChannelInitializer extends ChannelInitializer<SocketChannel>
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception
ChannelPipeline pipeline = socketChannel.pipeline();
pipeline.addLast(new ProtobufVarint32FrameDecoder());
pipeline.addLast(new ProtobufDecoder(MessageProto.RequestMsg.getDefaultInstance()));
pipeline.addLast(new ProtoBufServerHandler());
服务端handler:
public class ProtoBufServerHandler extends ChannelInboundHandlerAdapter
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception
MessageProto.ResponseMsg.Builder builder = MessageProto.ResponseMsg.newBuilder();
builder.setMsgType(ByteString.copyFromUtf8("CBSP"));
builder.setReceiveOne("小红");
builder.setMsg("你好,你有啥事");
ctx.writeAndFlush(builder.build());
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
MessageProto.RequestMsg m = (MessageProto.RequestMsg)msg;
System.out.println("Client say: "+m.getReceiveOne()+","+m.getMsg());
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
super.exceptionCaught(ctx, cause);
ctx.close();
客户端:
public class ProtoBufClient
private int port;
private String address;
public ProtoBufClient(int port, String address)
this.port = port;
this.address = address;
public void start()
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.handler(new ClientChannelInitializer());
try
ChannelFuture future = bootstrap.connect(address,port).sync();
future.channel().closeFuture().sync();
catch (Exception e)
e.printStackTrace();
finally
group.shutdownGracefully();
public static void main(String[] args)
ProtoBufClient client = new ProtoBufClient(7788,"127.0.0.1");
client.start();
客户端Initializer:
public class ClientChannelInitializer extends ChannelInitializer<SocketChannel>
protected void initChannel(SocketChannel socketChannel) throws Exception
ChannelPipeline pipeline = socketChannel.pipeline();
pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
pipeline.addLast(new ProtobufEncoder());
pipeline.addLast(new ProtoBufClientHandler());
客户端handler:
public class ProtoBufClientHandler extends ChannelInboundHandlerAdapter
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
MessageProto.ResponseMsg m = (MessageProto.ResponseMsg)msg;
System.out.println("Server say: "+m.getReceiveOne()+","+m.getMsg());
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception
MessageProto.RequestMsg.Builder builder = MessageProto.RequestMsg.newBuilder();
builder.setMsgType(ByteString.copyFromUtf8("CBSP"));
builder.setReceiveOne("小明");
builder.setMsg("你好,我找你有事");
ctx.writeAndFlush(builder.build());
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception
System.out.println("Client is close");
启动服务端和客户端,输出如下:
最简单的protoBuf应用案例我们就写完了,真实的使用场景大同小异,随机应变即可。
近期热文推荐:
1.1,000+ 道 Java面试题及答案整理(2021最新版)
2.终于靠开源项目弄到 IntelliJ IDEA 激活码了,真香!
3.阿里 Mock 工具正式开源,干掉市面上所有 Mock 工具!
4.Spring Cloud 2020.0.0 正式发布,全新颠覆性版本!
觉得不错,别忘了随手点赞+转发哦!
netty4.xunity与netty使用protobuf(代码片段)
...的特点是数据小、编解码性能高、支持多种语言,它序列化后的大小是json的10分之一,xml格式的20分之一,是二进制序列化的10分之一。更加详细请阅读下面2篇文章:【GoogleProtobuf】windows下protobuf的环境搭建(一)【G... 查看详情
protobuf源码解析与netty+rpc实战(代码片段)
...tobuf2.1protobuf工作流程protobuf全称是protocolbuffers,它是一个序列化/反序列化框架 查看详情
美团大牛熬夜亲码netty全栈笔记太强了!入门/中级/高级/源码/架构全都有!
...xff0c;阿里分布式服务框架Dubbo、RocketMQ,大数据的基础序列化和通信框架Avro,以及很多开源的软件都已经开始使用Netty来构建高性能、分布式通信能力,Netty社区的活跃度也名列前茅。今天给大家整理了一份有关Netty的... 查看详情
十一.netty入门到超神系列-netty使用protobuf编码解码(代码片段)
前言数据在网络传输的过程中需要序列化或和反序列化,也就需要用到编码器和解码器,本篇文章主要是探讨Netty中的编码解码器以及Protobuf的使用。Netty中的编码解码当我们的Netty客户端和服务端进行通信时数据在传输的... 查看详情
美团大牛熬夜亲码netty全栈笔记太强了!入门/中级/高级/源码/架构全都有!
Netty什么?你现在会觉得使用Netty编程的难度和工作量大了吗?Netty是一个令人惊讶的项目,在短短几年内成为众多Java高并发异步通信的首选框架。Netty作为成熟的高性能异步通信框架,无论是在互联网分布式应用... 查看详情
netty系列之:在netty中使用protobuf协议
...有很多适配不同协议的编码工具,对于流行的google出品的protobuf也不例外。netty为其提供了ProtobufDecoder和ProtobufEncoder两个工具还有对应的framedetection,接下来我们会通过一个例子来详细讲解如何在netty中使用protobuf。定义protobuf我们... 查看详情
netty编解码之java原生序列化
netty序列化之java原生序列化前几天有空看了下netty使用java原生序列化、以及使用protobuf、jbossmarshalling进行编解码,各种技术之间差异挺大,使用的方法各自不同,性能上原生的性能优势确实不大,但是另外两种确... 查看详情
java示例代码_如何最好地指定与Netty一起使用的Protobuf(最好使用内置的Protobuf支持)
java示例代码_如何最好地指定与Netty一起使用的Protobuf(最好使用内置的Protobuf支持) 查看详情
netty_05_六种序列化方式(javaio序列化xml序列化hessian序列化json序列化protobuf序列化avro序列化)(实践类)
文章目录一、普通的序列化方式(bean对象有直接的java类)1.1普通的javaiobyteArray输入输出流的序列化方式1.2xml序列化方式(xml用来做配置文件,这样序列化出来长度很大)1.3Hessian序列化方式(这个Dubbo中使用的序列化... 查看详情
protobuf编译安装
...吧,网上对比的文章很多,我主要关注以下几点1、protobuf序列化性能最好,序列化后字节数最少。2、protobuf是单纯的序列化框架,不自带通信层,因为通信层我要用mina或netty,之前用的比较多,比较熟悉。3、avro序列化的时候,... 查看详情
netty编解码之jbossmarshalling
netty编解码之jbossmarshallingjbossmarshalling是jboss内部的一个序列化框架,速度也十分快,这里netty也提供了支持,使用十分方便,不需要像protobuf一样编写proto文件,只需要提供两个编解码器即可,以下就是jbossm... 查看详情
springboot启动事件和监听器,太强大了!
...ring框架必学的核心知识之一。一般来说,我们很少会使用到应用程序事件,但我们也不要忘了它们的存在,比如说在Spring框架内部都使用了各种不同的事件来处理不同的任务。毫无疑问,在SpringBoo 查看详情
day475.googleprotobuf&netty编解码器和handler的调用机制-netty(代码片段)
...象或各种业务对象的编码和解码,底层使用的仍是Java序列化技术,而Java序列化技术本身效率就不高,存在如下问题无法跨语言序列化后的体积太大,是二进制编码的5倍多。序列化性能太低引出新的解决方案[Google的Prot... 查看详情
day475.googleprotobuf&netty编解码器和handler的调用机制-netty(代码片段)
...象或各种业务对象的编码和解码,底层使用的仍是Java序列化技术,而Java序列化技术本身效率就不高,存在如下问题无法跨语言序列化后的体积太大,是二进制编码的5倍多。序列化性能太低引出新的解决方案[Google的Prot... 查看详情
netty_05_六种序列化方式(javaio序列化xml序列化hessian序列化json序列化protobuf序列化avro序列化)(实践类)
文章目录一、普通的序列化方式(bean对象有直接的java类)1.1普通的javaiobyteArray输入输出流的序列化方式1.2xml序列化方式(xml用来做配置文件,这样序列化出来长度很大)1.3Hessian序列化方式(这个Dubbo中使用的序列化... 查看详情
idea一键生成maven依赖关系图,太强大了。。
...图点击MavenProject视图,如果此视图没有打开,请使用View菜单将其打开。操作2:显 查看详情
10.netty客户端与服务器使用protobuf传输报文(代码片段)
...f1a; netty的编码器与解码器;netty客户端与服务器通过protobuf 传输报文的开发方式;文末po出了所有代码;【1】netty的编码器与解码器codec1)编解码器应用场景编写网络应用程序时,因为数据在网络中 查看详情
太强大了,feign对接yapi实现自动mock
原创:猿天地(微信公众号ID:cxytiandi),欢迎分享,转载请保留出处。前面我们介绍了在微服务架构下如何解决单测时Mock的问题,通过Mock可以在单测时不依赖其他服务的实现。在文章最后我也给大家提供了一个思考题:是不... 查看详情