首页 技术 正文
技术 2022年11月14日
0 收藏 963 点赞 2,299 浏览 5714 个字

Google Protobuf是一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

编译安装:

下载Java版 https://github.com/google/protobuf/releases

tar -zxvf xxx.tar.gz

./configure

make

make install

protoc –version

mvn install

mvn package

使用:

Google Protobuf支持复杂的POJO对象的编解码,而这些代码是自动生成的。

首先写文件Person.proto ,定义程序中需要处理的结构化数据,在 protobuf 的中,结构化数据被称为 Message。

syntax="proto3";
package com.luangeng.netty.protobuf; message Person {
string username=1; //
int32 age=2; //
string sex=3; //
}

执行命令

protoc -I=. –java_out=. Person.proto

格式: protoc -I=$SRC_DIR –cpp_out=$DST_DIR $SRC_DIR/***.proto

即在当前目录下生成了Java文件PersonOutClass.java, 将它引入到工程并需要添加POM依赖

<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.5.0</version>
</dependency>

然后做一个简单的编解码测试:

public class TestProtoBuf {    //编码为byte数组
private static byte[] encoder(PersonOuterClass.Person p) {
return p.toByteArray();
} //从byte数组解码
private static PersonOuterClass.Person decoder(byte[] b) throws InvalidProtocolBufferException {
return PersonOuterClass.Person.parseFrom(b);
} //使用builder实例来设置属性
private static PersonOuterClass.Person create(){
PersonOuterClass.Person.Builder builder = PersonOuterClass.Person.newBuilder();
builder.setAge(10);
builder.setSex("man");
builder.setUsername("luangeng");
return builder.build();
} public static void main(String[] args) throws InvalidProtocolBufferException {
PersonOuterClass.Person p = create();
Q.p("before----------\n" + p.toString()); PersonOuterClass.Person p2 = decoder(encoder(p));
Q.p("afetr-----------\n" + p2.toString());
}}

输出结果:

before———-
username: “luangeng”
age: 10
sex: “man”

afetr———–
username: “luangeng”
age: 10
sex: “man”

在Netty中使用Google Protobuf实例:

Server端:

public class EchoServer {
public static void main(String[] args) {
new EchoServer().bind(8080);
} public void bind(int port) {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new ProtobufVarint32FrameDecoder());
ch.pipeline().addLast(new ProtobufDecoder(PersonOuterClass.Person.getDefaultInstance()));
ch.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());
ch.pipeline().addLast(new ProtobufEncoder());
ch.pipeline().addLast(new EchoServerHandler());
}
});
ChannelFuture future = bootstrap.bind(port).sync();
System.out.println("server started");
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("server shuting down");
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}public class EchoServerHandler extends ChannelInboundHandlerAdapter {
int count = 0; @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
PersonOuterClass.Person p = (PersonOuterClass.Person) msg;
System.out.println("Server received " + count++ + " :\n" + p.toString());
ctx.writeAndFlush(msg);
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}

Client端:

public class EchoClient {    public static void main(String[] args) {
new EchoClient().connect("127.0.0.1", 8080);
} public void connect(String host, int port) {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new ProtobufVarint32FrameDecoder());
ch.pipeline().addLast(new ProtobufDecoder(PersonOuterClass.Person.getDefaultInstance()));
ch.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());
ch.pipeline().addLast(new ProtobufEncoder());
ch.pipeline().addLast(new EchoClientHandler());
}
});
ChannelFuture future = bootstrap.connect(host, port).sync();
System.out.println("client started");
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("client shuting down");
group.shutdownGracefully();
}
}
}public class EchoClientHandler extends ChannelInboundHandlerAdapter { private int count = 0; private static PersonOuterClass.Person create(int i) {
PersonOuterClass.Person.Builder builder = PersonOuterClass.Person.newBuilder();
builder.setAge(i);
builder.setSex("man");
builder.setUsername("luangeng" + i);
return builder.build();
} @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
for (int i = 0; i < 20; i++) {
ctx.writeAndFlush(create(i));
}
} //服务端返回应答信息后调用
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
PersonOuterClass.Person p = (PersonOuterClass.Person) msg;
Q.p("Client get " + count++ + " :\n" + p.toString());
} @Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}

执行结果:

client started
Client get 0 :
username: “luangeng0”
sex: “man”

Client get 1 :
username: “luangeng1”
age: 1
sex: “man”

Client get 2 :
username: “luangeng2”
age: 2
sex: “man”

Client get 3 :
username: “luangeng3”
age: 3
sex: “man”

Client get 4 :
username: “luangeng4”
age: 4
sex: “man”

Client get 5 :
username: “luangeng5”
age: 5
sex: “man”

Client get 6 :
username: “luangeng6”
age: 6
sex: “man”

Client get 7 :
username: “luangeng7”
age: 7
sex: “man”

Client get 8 :
username: “luangeng8”
age: 8
sex: “man”

Client get 9 :
username: “luangeng9”
age: 9
sex: “man”

Client get 10 :
username: “luangeng10”
age: 10
sex: “man”

Client get 11 :
username: “luangeng11”
age: 11
sex: “man”

Client get 12 :
username: “luangeng12”
age: 12
sex: “man”

Client get 13 :
username: “luangeng13”
age: 13
sex: “man”

Client get 14 :
username: “luangeng14”
age: 14
sex: “man”

Client get 15 :
username: “luangeng15”
age: 15
sex: “man”

end

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,077
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,552
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,401
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,176
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,813
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,896